#!/bin/bash
########################################################################
####  Script Name: system virtual machine installer: svmi
####  Only use for Debian Sid, Testing and Stable, no support for any other distro
####  version: 2.8.60
####  Date: 2015-07-03
########################################################################
####  Copyright (C) Harald Hope 2007-2014
####  This program is free software; you can redistribute it and/or modify it under
####  the terms of the GNU General Public License as published by the Free Software
####  Foundation; either version 3 of the License, or (at your option) any later version.
####
####  This program is distributed in the hope that it will be useful, but WITHOUT
####  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
####  FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
####
####  Get the full text of the GPL here:
####  http://www.gnu.org/licenses/gpl.html
########################################################################
####  Script URL: http://smxi.org/sv/svmi
####  Script SVN: http://code.google.com/p/svmi
####  Script Documentation: http://smxi.org/docs/
####  Script Home Forums: http://techpatterns.com/forums/forum-33.html
########################################################################
#### DEFINE:
#### TRUE: -eq 0; == 'true'; function return 0
#### FALSE: -gt 0; == ''; function return > 0
########################################################################
####  CONVENTIONS:
####  Indentation: TABS
####  Do not use `....`, those are totally non-reabable, use $(....)
####  Do not use one liner flow controls. The ONLY time you should use ; is in
####  this single case: if [ condition ];then (ie, never: [ condition ] && statement)
####
####  All new code/methods must be in a function.
####  For all boolean tests, use 'true' / 'false'. Do NOT use 0 or 1 unless
####  it's a function return. Avoid complicated tests in the if condition itself.
####
####  VARIABLE/FUNCTION NAMING:
####  All variables should explain what they are, except counters like i, j
####  All variables MUST be initialized / declared explicitly
####, globals UPPER CASE, at top of script, SOME_VARIABLE='' (words separated by _ ).
####  Locals always: local someVariable= (lower case, all except first word started upper case)
####  and at the top of the function. ie: testTrunkData
####
####  Booleans should start with b_ or B_ and state clearly what is being tested
####	Arrays should start with a_ or A_
####  All functions should follow standard naming, ie, verb adjective noun, get_cpu_data
########################################################################
####  TESTING FLAGS
####  svmi supports advanced testing triggers to do various things, using -! <arg>
####  -! 1 - triggers default B_TESTING_1='true' to trigger some test or other
####  -! 2 - triggers default B_TESTING_2='true' to trigger some test or other
####  -! 3 - triggers default B_SKIP_FUNCTION='true' to turn off some functions
####  -! 4 - triggers B_TESTING_1='true' and B_TESTING_2='true'
####  -! 5 - triggers B_TESTING_1='true' and B_SKIP_FUNCTION='true'
####  -! 10 - triggers an update from the primary dev download server
####  -! 11 - triggers an update from svn branch one - if present, of course
####  -! 12 - triggers an update from svn branch two - if present, of course
####  -! <http://......> - Triggers an update from whatever server you list.
########################################################################
#### VARIABLES
########################################################################

# script global data
NON_DEBIAN_PATTERN='(deb-ats|deb-mep|deb-mm4.2.8-83876|deb-multimedia|deb-op|deb-sdx|deb-skp|deb-swift|deb-vb|alphagemini|aptosid|byteme|cathbard|debian-multimedia|dotdeb|edevelop|eeepc|freevo|giss.tv|google|java|kanotix|kde|kiberpipa|kplayer|lamaresh|liquorix|lxde|mepis|moblock|opera|noreply|prodeia.de|rarewares|rox4debian|siduction|sidux|skype|swiftfox|tovid|videolan|virtualbox|wine-hq|xadras)'

# options and global data
APT_TYPE='apt-get'
AUTO_RUN=''
AUTORUN_ANYANY=''
AUTORUN_QEMU_IMAGE=''
AUTORUN_VBOX=''
AUTORUN_VBOX_MODULE=''
AUTORUN_VMPLAYER=''
AUTORUN_VMSERVER=''
B_SKIP_FUNCTION=''
B_TESTING_1=''
B_TESTING_2=''
FORCE_UPDATE=''
SCRIPT_COLORS=1
PACKAGE_MANAGER=''
SKIP_CONNECT=''
SKIP_RESTART=''
SM_INSTALL=''
START_OPTIONS=''
SYSTEM_BASE=''
UPDATED=''
USER_NAME=''
V_ALT_VERSION=''
WITHOUT_RECOMMENDS=''

# system paths etc
EAA='/etc/apt/apt.conf'
EAS='/etc/apt/sources.list'
EDV='/etc/debian_version'
EDVV='/etc/devuan_version'
EMOD='/etc/modules'
SCRIPT_DOWNLOAD='http://smxi.org/sv/'
SCRIPT_DOWNLOAD_DEV='http://techpatterns.com/downloads/distro/'
SCRIPT_DOWNLOAD_BRANCH_1='http://svmi.googlecode.com/svn/branches/one/'
SCRIPT_DOWNLOAD_BRANCH_2='http://svmi.googlecode.com/svn/branches/two/'
USRS='/usr/src/'
SCRIPT_WORKING_DIR="${USRS}svmi-downloads"
VMWARE_INSTALL_PATH="${SCRIPT_WORKING_DIR}/vmware"
VMWARE_CONFIG='/usr/bin/vmware-config.pl'

# kernel info
KERNEL_FULL=$(uname -r)

if [ -n "$( grep -Es '^[3-9]\.' <<< $KERNEL_FULL )" ];then
	KERNEL_BASE=$( echo $KERNEL_FULL | cut -d '.' -f 1 ) # like: 3
	KERNEL_NUMBER=$( echo $KERNEL_FULL | cut -d '-' -f 1 | cut -d '.' -f 1-2 ) # like: 3.19
	KERNEL_MATH=$( echo $KERNEL_FULL | cut -d '-' -f 1 | cut -d '.' -f 2 ) # like: 19
else
	KERNEL_BASE=$( uname -r | cut -d '.' -f 1-2 ) # like: 2.6
	KERNEL_NUMBER=$( uname -r | cut -d '-' -f 1 | cut -d '.' -f 1-3 ) # like: 2.6.19
	KERNEL_MATH=$( uname -r | cut -d '-' -f 1 | cut -d '.' -f 3 ) # like: 19, for math use
fi

# check for 64 bit first
if [ -n "$( uname -m | grep -o 'x86_64' )" ];then
	BITS="64"
else
	BITS="32"
fi

# set some core count dependent data
CORE_COUNT=$( cat /proc/cpuinfo | grep -c '^processor' )

INSTALL_TYPE=''
VMP='vmplayer'
AA='anyany'

DIR_NAME=''
FILE_NAME=''
FILE_URL=''
## extra url data.. for vmware tools:
# note: 3.0.x not available for direct download, oh well... that should help send more
# users to virtualbox, too bad since vmware player is superior in most ways, but that's life..
# http://download3.vmware.com/software/wkst/VMware-workstation-5.5.0-18463.tar.gz
# http://download3.vmware.com/software/vmplayer/VMware-player-2.0.2-59824.i386.tar.gz
# http://download3.vmware.com/software/vmplayer/VMware-player-2.0.2-59824.x86_64.tar.gz
# http://download3.vmware.com/software/vmplayer/VMware-Player-2.5.1-126130.i386.bundle
# VMware-player-2.0.2-59824 VMware-workstation-5.5.0-18463 2.0.4-93057
VMPLAYER_PREFIX='http://download3.vmware.com/software/vmplayer/'
# Two version will be supported: previous major, latest, and current major
VMPLAYER_NUMBER_PREVIOUS='2.0.5'
VMPLAYER_BUILD_PREVIOUS='109488'
VMWARE_NAME_PREVIOUS='VMware-player'
# current version
# 2.5.2 156735;2.5.0 118166;2.5.1 126130;
VMPLAYER_NUMBER='2.5.3'
VMPLAYER_BUILD='185404'
VMWARE_NAME='VMware-Player'
VMPLAYER_INSTALLED='' # set only if required
# only for dev/debugging purposes
VMPLAYER_NUMBER_TESTING=''
VMPLAYER_BUILD_TESTING=''

VMPLAYER_VERSION="$VMWARE_NAME-$VMPLAYER_NUMBER-$VMPLAYER_BUILD"
VMPLAYER_VERSION_PREVIOUS="$VMWARE_NAME_PREVIOUS-$VMPLAYER_NUMBER_PREVIOUS-$VMPLAYER_BUILD_PREVIOUS"
VMWARE_Z='.bundle'
VMWARE_Z_PREVIOUS='.tar.gz'
if [ "$BITS" -eq 32 ];then
	VMWARE_32_64='.i386'
else
	VMWARE_32_64='.x86_64'
fi
VMPLAYER_RUN='vmware-install.pl'
VMPLAYER_DIR='vmware-player-distrib'

# ANYANY_ALT='http://rtr.ca/vmware-2.6.24/vmware-any-any-update115a.tgz'
# http://linuxtoy.org/files/vmware-any-any-update-116.tgz
# http://groups.google.com/group/vmkernelnewbies/web/vmware-any-any-update-116.tgz
ANYANY_PREFIX='http://knihovny.cvut.cz/ftp/pub/vmware/'
# ANYANY_PREFIX='http://groups.google.com/group/vmkernelnewbies/web/'
ANYANY_VERSION='vmware-any-any-update'
ANYANY_NUMBER=115 # we'll be doing some math on this maybe
# ANYANY_Z='.tar.gz'
ANYANY_Z='.tar.gz'
ANYANY_RUN='runme.pl'
ANYANY_ALT=''
ANYANY_DIR_DASH=''
ANYANY_FILE_DASH=''

# # # use alternate name and location for 2.6.24
case $KERNEL_BASE in
	2.6)
		case $KERNEL_MATH in
			26)
				# source url:
				# http://groups.google.com/group/vmkernelnewbies/web/vmware-any-any-update117c.tar.gz
				# author blog:
				# http://opensuse-linux-blog.blogspot.com/2008/07/how-to-install-vmware-in-2626-linux.html#links
				ANYANY_PREFIX='http://smxi.org/sv/patches/'
				#ANYANY_Z='.tgz' # note, moving to 'd' patch from 'c'
				ANYANY_ALT='d'
				ANYANY_NUMBER=117
				#ANYANY_FILE_DASH=''
				;;
			25)
				# http://download.rsbac.org/tmp/vmware-any-any-update117.tar.gz
				# vmware-any-any-update-116.tgz
				ANYANY_PREFIX='http://download.rsbac.org/tmp/'
				#ANYANY_Z='.tgz'
				#ANYANY_ALT=''
				ANYANY_NUMBER=117
				#ANYANY_FILE_DASH=''
				;;
			24)
				# http://blog.creonfx.com/temp/vmware-any-any-update-116.tgz
				ANYANY_PREFIX='http://smxi.org/sv/patches/'
				ANYANY_Z='.tgz'
				ANYANY_ALT='a'
				ANYANY_NUMBER=115
				;;
		esac
		;;
	3)
		: # nothing yet
		;;
esac

APT_VBOX_VERSION_NU=''
VBOX_INSTALL_PATH="${SCRIPT_WORKING_DIR}/vbox"
VBOX_EXTENSION_NO='100309'
VBOX_PACKAGE_NO='100309'
VBOX_VERSION='4.3.28'
VBOX_SEPARATOR='~' # note random changes in path components...
# 4.3.18-96516 4.3.22-98236 4.3.26-98988
# 4.3.6-91406 4.3.8-92456 4.3.10-93012 4.3.12-93733 4.3.14-95030  4.3.16-95972
# 4.2.8-83876 4.2.10-84104 4.2.12-84980 4.2.16-86992
# 4.1.20-80170 4.1.22-80657 4.2.0-80737 4.2.2-81494 4.2.4-81684 4.2.6-82870
# http://.../4.3.0/virtualbox-4.3_4.3.0-89960~Debian~wheezy_i386.deb
# http://.../4.2.18/virtualbox-4.2_4.2.18-88780~Debian~wheezy_i386.deb
# http://.../4.2.14/virtualbox-4.2_4.2.14-86644~Debian~wheezy_amd64.deb
# http://.../4.2.8/virtualbox-4.2_4.2.8-83876~Debian~wheezy_i386.deb
# http://.../4.1.12/virtualbox-4.1_4.1.12-77245~Debian~squeeze_amd64.deb
# http://.../4.1.10/virtualbox-4.1_4.1.10-76795~Debian~wheezy_amd64.deb
# http://.../4.1.8/virtualbox-4.1_4.1.8-75467~Debian~squeeze_i386.deb
# http://.../4.1.6/virtualbox-4.1_4.1.6-74713~Debian~squeeze_amd64.deb
# http://.../3.2.0/virtualbox-3.2_3.2.0-61806~Debian~lenny_i386.deb
# http://.../3.1.8/virtualbox-3.1_3.1.8-61349~Debian~lenny_i386.deb
# http://.../3.1.6/virtualbox-3.1_3.1.6-59338_Debian_lenny_amd64.deb
# http://.../3.1.4/virtualbox-3.1_3.1.4-57640_Debian_lenny_i386.deb
# http://.../3.1.2/virtualbox-3.1_3.1.2-56127_Debian_lenny_amd64.deb
# http://.../3.1.0/virtualbox-3.1_3.1.0-55467_Debian_lenny_i386.deb
# http://.../3.0.12/virtualbox-3.0_3.0.12-54655_Debian_lenny_i386.deb
## previous versions
# 1.5.0:24069 1.5.2:25433 1.5.4:27034 1.5.6:28266 1.6.0:30421 1.6.2:31466 1.6.4:33808
# 2.0.0:36011 2.0.2:36488 2.0.4:38406 2.0.6:39765 2.1.0:41146 2.1.2:41885 2.2.0:45846
# 2.2.2:46594 3.0.0:49315 3.0.2:49928 3.0.8:53138 3.0.10:54097 3.0.12:54655 3.1.0:55467
# 3.1.2:56127 3.1.4:57640 3.1.6:59338 3.1.6:59338:_ 3.1.8:61349:~ 3.2.0:61806:~
# 3.2.0:61806:~ 3.2.2:62298:~ 3.2.4:62467:~ 3.2.6:63112:~ 3.2.8:64453:~ 3.2.10:66523:~
# 3.2.12:68302:~ 
# 4.0.2:69518:~:69518 4.0.4:70112:~:70112 4.0.6:71344:~:71344 4.0.8:71778:~:71778 
# 4.0.10:72479:~:72436 4.0.12:72916:~:72916
# 4.1.0:73009:~:73009 4.1.2:73507:~:73507 4.1.4:74291:~:74291 4.1.6:74713:~:74713 
# 4.1.8:75467:~:75467 4.1.10:76795:~:76795 4.1.12:77245:~:77245 4.1.14:77440:~:77440   
# 4.1.16:78094:~:78094 4.1.18:78361:~:78361 4.1.20:80170:~:80170 4.1.22:80657:~:80657
# 4.2.0:80737:~:80737 4.2.2:81494:~:81494 4.2.4:81684:~:81684 4.2.6:82870:~:82870 4.2.8:83876:~:83876 
# 4.2.10:84104:~:84104 4.2.12:84980:~:84980 4.2.14:86644:~:86644 4.2.16:86992:~:86992 4.2.18:88780:~:88780 
# 4.3.0:89960:~:89960 4.3.2:90405:~:90405 4.3.4:91027:~:91027 4.3.6:91406:~:91406 4.3.8:92456:~:92456 
# 4.3.10:93012:~:93012 4.3.12:93733:~:93733 4.3.14:95030:~:95030 4.3.16:95972:~:95972 4.3.20:96996:~:96996 
# 4.3.22:98236:~:98236 4.3.24:98716:~:98716 4.3.26:98988:~:98988 4.3.28:100309:~:100309 ::~: ::~: ::~: ::~: ::~: ::~: ::~: ::~: ::~: ::~: 
VBOX_PREVIOUS="1.6.6:35336:_ 2.0.6:39765:_ 2.1.4:42893:_ 2.2.4:47978:_ 3.0.12:54655:_ 3.1.8:61349:~ 3.2.12:68302:~ 4.0.12:72916:~:72916 4.1.22:80657:~:80657 4.2.18:88780:~:88780 $VBOX_VERSION:$VBOX_PACKAGE_NO:$VBOX_SEPARATOR:$VBOX_EXTENSION_NO"
# this is just for cosmetic output of supported versions
VBOX_VERSIONS=$( echo $VBOX_PREVIOUS | grep -Eo '[0-9]\.[0-9]\.[0-9]' )
VBOX_VERSIONS=$( echo $VBOX_VERSIONS ) # dump the line breaks
VBOX_INSTALLED_VERSION='' # will be set dynamically
VBOX_DOWNLOAD_SERVER='http://download.virtualbox.org/virtualbox/'

# script paths
EAA='/etc/apt/apt.conf'
EAS='/etc/apt/sources.list'
SCRIPT_HOME='/usr/local/bin'
SCRIPT_NAME=$( basename $0 )
SM_KERNEL_DOWNLOADS="${USRS}sm-kernel-downloads"
SM_VALUES='/usr/local/bin/svmi-values'

CONFIG_FILE='/etc/svmi.conf'
LOG_FILE='/var/log/svmi.log'
LOGPS='log_function_data ps $FUNCNAME "$( echo $@ )"'
LOGPE='log_function_data pe $FUNCNAME'
LOGUS='log_function_data us $FUNCNAME "$( echo $@ )"'
LOGUE='log_function_data ue $FUNCNAME'
LOGGING_STARTED='' # this will flag to avoid logging for pre log errors like no root
SCRIPT_ROTATE="/etc/logrotate.d/$SCRIPT_NAME"

# miscellaneous settings
TIME_OUT=25
DOWNLOAD_COUNTER=0

# allow user set globals to override script globals
if [ -f $SM_VALUES ];then
	source $SM_VALUES
fi

########################################################################
####  FUNCTIONS
########################################################################

# args: $1 vbox/vmplayer
apply_fixes_post_install()
{
	eval $LOGUS
	local modulePatch=''
	
	case $1 in
		vbox)
			:
			;;
		vmplayer)
			log_function_data "VMPLAYER_NUMBER: $VMPLAYER_NUMBER - KERNEL_MATH $KERNEL_MATH"
			case $KERNEL_BASE in
				2.6)
					case $KERNEL_MATH in
						29)
							case $VMPLAYER_NUMBER in
								# patch logic: http://communities.vmware.com/thread/192355
								# patch src: http://communities.vmware.com//message/1213099
								# patch url:http://communities.vmware.com/servlet/JiveServlet/download/1213099-20834/vmware-modules-2.6.29.patch.gz  
								2.5.1)
									modulePatch='vmware-modules-2.6.29-2.5.1-2.patch'
									vmplayer_quick_fix "$modulePatch"
									;;
								2.5.2)
									#patch src: http://communities.vmware.com/thread/203231
									modulePatch='vmware-modules-2.6.29-2.5.2-1.patch'
									vmplayer_quick_fix "$modulePatch"
									;;
							esac
							;;
						30)
							case $VMPLAYER_NUMBER in
								# patch source: http://communities.vmware.com/thread/208963
								2.5.2)
									#patch src: http://communities.vmware.com/thread/203231
									# modulePatch='vmware-modules-2.6.30-2.5.2-1.patch'
									# src: http://communities.vmware.com/thread/208963
									modulePatch='vmware-modules-2.6.30-2.5.2-2.patch'
									vmplayer_quick_fix "$modulePatch"
									;;
		# 						2.5.3)
		# 							# src: http://communities.vmware.com/thread/221724
		# 							modulePatch='vmware-6.5.2-2.6.29-2.6.31.patch'
		# 							vmplayer_quick_fix "$modulePatch"
		# 							;;
							esac
							;;
						31)
							case $VMPLAYER_NUMBER in
								2.5.2)
									# src: http://communities.vmware.com/thread/221724
									modulePatch='vmware-6.5.2-2.6.29-2.6.31.patch'
									vmplayer_quick_fix "$modulePatch"
									;;
							esac
							;;
					esac
					;;
				3)
					: # nothing yet
					;;
			esac
			;;
	esac
	eval $LOGUE
}

apply_module_fixes()
{
	eval $LOGUS
	local modulePatch='' data1='' data2=''
	
	case $1 in
		vbox)
			:
			;;
		vmplayer)
			case $KERNEL_BASE in
				2.6)
					case $KERNEL_MATH in
						3[56789])
							case $VMPLAYER_INSTALLED in
								3.1.*)
									data1='/usr/lib/vmware/modules/source/vmmon.tar'
									echo "${S}Running module fix for ${C}$VMPLAYER_INSTALLED${S}...${N}"
									if [ -e "$data1" ];then
										cd /tmp
										tar xvf $data1 -C /tmp
										perl -pi -e 's,_range,,' vmmon-only/linux/iommu.c
										tar cvf $data1 vmmon-only
										cd $SCRIPT_HOME
									else
										error_handler 184 "$data1"
									fi
									;;
							esac
							;;
					esac
					;;
				3)
					: # nothing yet
					;;
			esac
			;;
	esac
	eval $LOGUE
}

# args: $1 - which patch to run
vmplayer_quick_fix()
{
	local i='' patchName=$1 patchUrl="$SCRIPT_DOWNLOAD/patches"
	local dirData='/usr/lib/vmware/modules/source/'
	local ua="-U s-tools/$SCRIPT_NAME.patches.$patchName"
	patchUrl="$patchUrl/$patchName"
	
	echo $LINE
	echo "${S}Retrieving patch for $VMPLAYER_NUMBER post install now...${N}"
	wget $ua -O ${VMWARE_INSTALL_PATH}/$patchName $patchUrl || error_handler 189
	echo "${S}Preparing system for patching now...${N}"
	if [ -d $dirData ];then
		cd $dirData
		mkdir orig
		cp -f *.tar orig/
		for i in $( ls *.tar )
		do 
			tar -xf $i
		done
		rm -f *.tar
		echo "${S}Applying patch now...${N}"
		patch -p1 -i ${VMWARE_INSTALL_PATH}/$patchName 2>> $LOG_FILE 2>&1
		echo "${S}Running post patch processes...${N}"
		for i in mblock mci mmon mnet mppuser sock
		do 
			tar -cf v$i.tar v$i-only
		done
		rm -rf *-only
		cd $SCRIPT_HOME # make sure to return to default
		echo "${S}All done with patching operation, hope it works for you!${N}"
	else
		echo "${W}NO $dirData found, cannot proceed!!${N}"
		print_hec
	fi
}

# only for debugging purposes
set_test_data()
{
	local username=''
	if [ "$B_TESTING_1" == 'true' ];then # set testing directories etc
# 		# this is required for testing to make sure we always are starting with true
# 		# latest script versions
		username=$( getent passwd 1000|cut -d \: -f1 )
		SCRIPT_HOME="/home/$username/bin/scripts/svmi/dev"
		LOG_FILE="$SCRIPT_HOME"svmi.log
		cd $SCRIPT_HOME
		VMWARE_INSTALL_PATH="$SCRIPT_HOME"
# 		VBOX_INSTALL_PATH="$SCRIPT_HOME"
		rm -f svmi.log
# 		SYSTEM_BASE='testing'
# 		KERNEL_MATH=31
# 		KERNEL_BASE=2.6
:
	fi
}

# temp function to set alternate versions
set_testing_version()
{
	if [ "$B_TESTING_2" == 'true' ];then
		VMPLAYER_NUMBER=$VMPLAYER_NUMBER_TESTING
		VMPLAYER_BUILD=$VMPLAYER_BUILD_TESTING
		VMPLAYER_VERSION="$VMWARE_NAME-$VMPLAYER_NUMBER-$VMPLAYER_BUILD"
	fi
}

# set global color variables
# options: 0 - turns off all colors; 1 - defaults
set_script_colors()
{
	# set colors
	case $SCRIPT_COLORS in
		0)
			W='' # red: Warning message
			E='' # yellow: script Error
			S='' # green: Standard message
			Q='' # CYAN: Questions
			M='' # CYAN: Message
			B='' # BLUE: Message
			C='' # MAGENTA: Command or Path
			N='' # default system console color: Normal :: make last in colors
			;;
		1)
			W="[1;31m" # red: Warning message
			E="[1;33m" # yellow: script Error
			S="[1;32m" # green: Standard message
			Q="[1;36m" # CYAN: Questions
			M="[1;36m" # CYAN: Message
			B="[1;34m" # BLUE: Message
			C="[1;35m" # MAGENTA: Command or Path
			N="[0;39m" # default system console color: Normal :: make last in colors
			;;
		2)
			W="[1;31m" # red: Warning message
			E="[1;33m" # yellow: script Error
			S="[0;37m" # Standard message
			Q="[0;36m" # CYAN: Questions
			M="[1;36m" # CYAN: Message
			B="[0;37m" # BLUE: Message
			C="[1;35m" # MAGENTA: Command or Path
			N="[0;39m" # default system console color: Normal :: make last in colors
			;;
		3)
			W="[1;31m" # red: Warning message
			E="[1;35m" # magenta: script Error
			S="[0;33m" # brown
			Q="[1;34m" # light blue: Questions
			M="[0;36m" # cyan: Message
			B="[0;33m" # brown: Message
			C="[0;32m" # green: Command or Path
			N="[0;39m" # default system console color: Normal :: make last in colors
			;;
		4)
			W="[0;31m" # red: Warning message
			E="[0;33m" # brown: script Error
			S="[0;34m" # blue: Standard message
			Q="[1;30m" # dark gray: Questions
			M="[1;30m" # dark gray: Message
			B="[0;34m" # blue: Message
			C="[0;35m" # purple: Command or Path
			N="[0;39m" # default system console color: Normal :: make last in colors
			;;
	esac

	CALLER_DEF=${S} # will switch default output color to the calling script's
	S=${B} # this is slightly tricky, making standard blue AFTER the caller def is set.

	# script layout stuff
	BA='=================================================================='
	LI='------------------------------------------------------------------'
	BAR=${S}$BA${N}
	EBAR=${E}$BA${N}
	WBAR=${W}$BA${N}
	MBAR=${M}$BA${N}
	LINE=${S}$LI${N}
	ELINE=${E}$LI${N}
	MLINE=${M}$LI${N}
	WLINE=${W}$LI${N}

	# repeated text
	YNE="\n${S}[ type lower case ${C}y${S} or ${C}n${S} and hit ${C}enter${S} ]${N}"
	SLE="${Q}Please type the appropriate number and hit ${C}enter${N}"
	HEC="${Q}Please hit ${C}enter${Q} to continue${N}"
}

# this will trigger the non interactive installs
run_non_interactive()
{
	if [ "$AUTORUN_ANYANY" == 'true' -o "$AUTORUN_QEMU_IMAGE" == 'true' -o "$AUTORUN_VBOX" == 'true' -o "$AUTORUN_VBOX_MODULE" == 'true' -o "$AUTORUN_VMPLAYER" == 'true' -o "$AUTORUN_VMSERVER" == 'true' ];then
		AUTORUN='true'
	fi

	if [ "$AUTORUN_ANYANY" == 'true' ];then
		install_vmware $AA
	fi
	if [ "$AUTORUN_QEMU_IMAGE" == 'true' ];then
		create_qemu_image
	fi
	if [ "$AUTORUN_VBOX" == 'true' ];then
		install_vbox
	fi
	if [ "$AUTORUN_VBOX_MODULE" == 'true' ];then
		install_vbox_module
	fi
	if [ "$AUTORUN_VMPLAYER" == 'true' ];then
		install_vmware $VMP
	fi
	if [ "$AUTORUN_VMSERVER" == 'true' ];then
		echo 'not currently working'
	fi
}
########################################################################
#### Error handling and detections
#### -------------------------------------------------------------------
error_handler()
{
	local errorCode=$1 # error number
	local errorExtra=$2 # this is secondary info, like failed package name
	local errorData=''
	local ErrorMessage=''

	case $errorCode in
		255)
			errorData="This does not appear to be a Debian apt based system!"
			;;
		254)
			errorData="Sorry, Ubuntu isn't supported by this script"
			;;
		253)
			errorData="Your kernel type $KERNEL_BASE is not supported for these drivers."
			;;
		252)
			errorData="You must be logged in as root to run this script."
			;;
		251)
			errorData="There does not appear to be a live connection, or $SCRIPT_NAME script server is down.\nIf you are sure you have a connection, restart script with -Z option to cancel connection test."
			;;
		250)
			errorData="Could not detect gcc version: $errorExtra, or it is not installed.\nPlease let the script maintainer know, this may be a bug in the script."
			;;
		249)
			errorData="The option you selected: $errorExtra is not supported."
			;;
		248)
			errorData="The file: $errorExtra appears to be corrupted. Please try to update again."
			;;
		247)
			errorData="Unsupported testing option argument: -! $errorExtra"
			;;
		246)
			errorData="There appears to be parts of virtualbox running. Please shutdown all\nvirtualbox components: Virtualbox Manager, and running guests, then try again."
			;;
		# specific install issues, non fatal cases
		200)
			errorData="The package: $errorExtra failed to install, please check apt for any problems."
			;;
		199)
			errorData="The file: $errorExtra failed to download - wget reports success."
			;;
		198)
			errorData="The url/file: $errorExtra\nfailed to download - wget error."
			;;
		197)
			errorData="The module: $errorExtra failed to build."
			;;
		196)
			errorData="Removing package $errorExtra failed."
			;;
		195)
			errorData="The package $errorExtra failed to download."
			;;
		194)
			errorData="The package $errorExtra failed to download and exceeded tries."
			;;
		193)
			errorData="tar xzf of $errorExtra failed."
			;;
		192)
			errorData="No vmware installation was detected for any-any install."
			;;
		191)
			errorData="The deb package $errorExtra failed to install correctly."
			;;
		190)
			errorData="Wget reports errors on download attempt for file:\n$errorExtra"
			;;
		189)
			errorData="Patching failed for $2"
			;;
		188)
			errorData="The required variable $errorExtra failed to set and is null."
			;;
		187)
			errorData="You appear to have the following virtualbox versions installed:\n $errorExtra\n$SCRIPT_NAME cannot know which you want to use here."
			;;
		186)
			errorData="${C}$errorExtra${E} does not appear to be installed, please install it using the menu options.\nYou cannot build the module without having first installed the $errorExtra!"
			;;
		185)
			errorData="${C}$VMPlayer${E} does not appear to be installed, please install it manually.\nYou must download it from vmware manually, then install it first!"
			;;
		184)
			errorData="Required directory ${C}$errorExtra${E} not detected, unable to patch."
			;;
		*)
			errorData="Unexpected Error !"
			;;
	esac
	ErrorMessage="ERROR: ($errorCode) $errorData"
	echo -e ${E}$ErrorMessage${N}
	if [ -f $LOG_FILE -a "$LOGGING_STARTED" == 'true' ];then
		log_function_data "$ErrorMessage"
		echo
		echo "${S}Log file is located here: $LOG_FILE"
	fi
	if [ "$errorCode" -gt 200 ];then 
		echo "${M}Exiting script now.${N}"
		exit $errorCode
	else
		echo $MLINE
		echo "${M}Continuing with script after non fatal Error Event: ${C}$errorCode${N}"
		print_hec
		return $errorCode
	fi
}

########################################################################
#### script utilities
#### -------------------------------------------------------------------

#print_information
basic_startup_tests()
{
	# set files to ram first, no need to keep reading them
	local edvContent='' easContent='' eaaContent=''
	if [ -f "$EDV" ];then
		edvContent="$( cat $EDV )"
	elif [ -f "$EDVV" ];then
		edvContent="$( cat $EDVV )"
	fi
	if [ -f "$EAS" -o -d "$EAS.d" ];then
		easContent="$( cat $EAS $EAS.d/*.list 2>/dev/null )"
	fi
	if [ -f "$EAA" ];then
		eaaContent="$( cat $EAA )"
	fi
	
	# these tests will be improved over time, but are ok for now
	local isEtch=$( grep -is '^4.' <<< "$edvContent" )
	local isLenny=$( grep -is '^5.' <<< "$edvContent" )
	local isSqueeze=$( grep -Eis '^(squeeze|6\.)' <<< "$edvContent" )
	local isWheezy=$( grep -Eis '^(wheezy|7\.)' <<< "$edvContent" )
	local isJessie=$( grep -Eis '^(jessie|8\.)' <<< "$edvContent" )
	local isStretch=$( grep -Eis '^(stretch|9\.)' <<< "$edvContent" )
	
	# first tests sources
	local isStable=$( grep -Esiw '^[[:space:]]*deb' <<< "$easContent" | grep -Eiv "$NON_DEBIAN_PATTERN" | grep -Eicw '(stable|wheezy|squeeze|lenny|etch|jesse)' )
	local isTesting=$( grep -Esiw '^[[:space:]]*deb' <<< "$easContent" | grep -Eiv "$NON_DEBIAN_PATTERN" | grep -Eicw '(stretch|testing)' )
	local isUnstable=$( grep -Esiw '^[[:space:]]*deb' <<< "$easContent" | grep -Eiv "$NON_DEBIAN_PATTERN" | grep -Eicw '(sid|unstable)' )
	
	# then test conf for default version
	local isStableDefault=$( grep -Esi 'APT::Default-Release[[:space:]]"(stable|etch|lenny|squeeze|wheezy|jesse)"' <<< "$eaaContent" )
	local isTestingDefault=$( grep -Esi 'APT::Default-Release[[:space:]]"(testing|stretch)"' <<< "$eaaContent" )
	local isUnstableDefault=$( grep -Esi 'APT::Default-Release[[:space:]]"(sid|unstable)"' <<< "$eaaContent" )
	
	### basic execute requirements
	cd $SCRIPT_HOME
	check_root
	
	# this allows users to update in x, for example, to see latest drivers
	if [ "$FORCE_UPDATE" == 'true' ];then
		check_update_script $SCRIPT_NAME "$SCRIPT_DOWNLOAD" 'default server'
	fi
	
	### basic system requirements for this script to run, first so user doesn't
	### have to be root or out of x to get basic failure information
	# make sure that it's a debian based system
	if [ ! -f "$EDV" -a ! -f "$EDVV" ];then
		error_handler 255
	fi
	# no ubuntu support
	if [ "$( cat /etc/issue | grep -i -c 'buntu' )" -gt 0 ];then
		error_handler 254
	fi
	# double check only 2.6 or newer series kernels, note double [[ and <
	if [[ "$KERNEL_BASE" < 2.6 ]];then
		error_handler 253
	fi

	# set system type. This test will never be perfect, but it's a good approximation
	if [ -n "$isEtch" -o -n "$isLenny" -o -n "$isSqueeze" -o -n "$isWheezy"  -o -n "$isJessie" -o -n "$isStableDefault" ] || [ "$isStable" -gt 0 -a "$isUnstable" -eq 0  -a "$isTesting" -eq 0 ];then
		if [ -n "$isEtch" ];then
			FG_DISTRIB_CODENAME='etch'
			SYSTEM_CODENAME='etch'
		elif [ -n "$isLenny" ];then
			FG_DISTRIB_CODENAME='lenny' # note: 'stable' breaks the installer
			SYSTEM_CODENAME='lenny'
		elif [ -n "$isSqueeze" ];then
			FG_DISTRIB_CODENAME='squeeze' # note: 'stable' breaks the installer
			SYSTEM_CODENAME='squeeze'
		elif [ -n "$isWheezy" ];then
			FG_DISTRIB_CODENAME='wheezy' # note: 'stable' breaks the installer
			SYSTEM_CODENAME='wheezy'
		elif [ -n "$isJesse" ];then
			FG_DISTRIB_CODENAME='jesse' # note: 'stable' breaks the installer
			SYSTEM_CODENAME='jesse'
		else
			FG_DISTRIB_CODENAME='stable'
			SYSTEM_CODENAME='stable'
		fi
	elif [ "$isUnstable" -eq 0 -o -n "$isTestingDefault" ] && [ -n "$isStretch" -o "$isTesting" -gt 0 ];then
		SYSTEM_BASE='testing'
	else
		SYSTEM_BASE='sid'
	fi
}

check_root()
{
	if [ "$(whoami)" != 'root' ];then
		error_handler 252
	fi
}

# handles bug in stub installer that leaves tempfiles uncleaned
cleanup_update_files()
{
	eval $LOGUS
	local all_files=""

	# Note: if  * is in "" the wildcard does not work
	# /dev/null handles case where no temp or original file exists
	all_files=$( ls "${SCRIPT_NAME}."* 2> /dev/null )
	# make sure stuff exists, rm files
	if [ -n "$all_files" ];then
		rm -f $all_files
	fi
	if [ ! -d $SM_KERNEL_DOWNLOADS -a -d /usr/src/kernel-downloads ];then
		mv -f /usr/src/kernel-downloads $SM_KERNEL_DOWNLOADS
	fi
	if [ ! -d "$SCRIPT_WORKING_DIR" ];then
		mkdir $SCRIPT_WORKING_DIR
	fi
	if [ -d /usr/src/vmware-downloads ];then
		mv -f /usr/src/vmware-downloads $VMWARE_INSTALL_PATH
	fi
	if [ -d /usr/src/vbox-downloads ];then
		mv -f /usr/src/vbox-downloads $VBOX_INSTALL_PATH
	fi
	eval $LOGUE
}

clean_script_data()
{
	check_root
	cd $SCRIPT_HOME
	
	local downloadDirectorySize=''
	local opt='' repeat='false'
	local options="remove-virtual-machine-downloads uninstall-$SCRIPT_NAME quit" 
	
	echo $MLINE
	echo "${M}$SCRIPT_NAME cleanup tool"
	echo $MLINE
	echo "${S}Calculating cleanup data....${N}"
	echo $LINE
	downloadDirectorySize=$( du -ch $SCRIPT_WORKING_DIR 2>/dev/null | grep 'total' )
	echo "${S}The following ${C}$SCRIPT_NAME${S} data exists for possible cleanup in your system"
	echo "$SCRIPT_WORKING_DIR: ${C}$downloadDirectorySize${S}"
	echo $LINE
	echo "${C}1 - remove-virtual-machine-downloads${S} - Delete ALL virtual machine driver downloads."
	echo "${C}2 - uninstall-$SCRIPT_NAME${S} - Removes ALL pieces of $SCRIPT_NAME. Cannot be undone."
	echo "   Will confirm your choice before proceeding."
	echo "${C}3 - quit${S} - Exit now."
	echo $LINE
	select opt in $options
	do
		case $opt in
			remove-virtual-machine-downloads)
				if [ -d $SCRIPT_WORKING_DIR ];then
					rm -rf $SCRIPT_WORKING_DIR
					echo "${C}$SCRIPT_WORKING_DIR${S} deleted. ${C}$downloadDirectorySize${S} cleaned up.${N}"
				else
					echo "${M}No ${C}$SCRIPT_WORKING_DIR${M} directory present so nothing deleted.${N}"
				fi
				repeat='true'
				;;
			uninstall-$SCRIPT_NAME)
				uninstall_script
				;;
			quit)
				echo "${S}Ok, quitting now.${N}"
				exit 0
				;;
			*)	print_error 'opt'
				repeat='true'
				;;
		esac
		break
	done
	
	if [ "$repeat" == 'true' ];then
		clean_script_data
	fi
}

uninstall_script()
{
	local opt=''
	local options="yes-uninstall-everything return-main-menu"
	echo $LINE
	echo "${S}Are you sure you want to totally uninstall ${C}$SCRIPT_NAME${S}"
	echo "This will remove $SCRIPT_NAME and all its components permanently!"
	echo $LINE
	echo "${S}Enter a number for your selection and hit enter"
	echo $LINE
	echo "${C}1 - yes-uninstall-everything${S} - Completely uninstall $SCRIPT_NAME and its related."
	echo "    components, logs, and configurations."
	echo "${C}2 - return-main-menu${S} - Go back to main menu, skip the uninstall."
	echo $LINE
	select opt in $options
		do
			case $opt in
				yes-uninstall-everything)
					echo "${S}Ok, removing all the pieces now...${N}"
					rm -f /var/log/${SCRIPT_NAME}*
					rm -f /etc/logrotate.d/${SCRIPT_NAME}*
					rm -rf $SCRIPT_WORKING_DIR
					rm -f $SCRIPT_HOME/${SCRIPT_NAME}*
					echo "${S}Ok, everything is removed. Exiting since $SCRIPT_NAME is now gone.${N}"
					exit 0
					;;
				return-main-menu)
					echo "${S}Ok, going back to cleanup menu now.${N}"
					;;
			esac
			break
	done
	
	if [ "$repeat" == 'true' ];then
		uninstall_script
	fi
}

check_install_tools()
{
	eval $LOGPS
	local gccVersion=$( grep -Eio 'gcc[[:space:]]*version[[:space:]]*[4-6]\.[0-9]{1,2}' /proc/version | grep -Eo '[4-6]\.[0-9]{1,2}' )
	# as of gcc-5, gcc and g++ are without decimal
	if [ -n "$gccVersion" -a -n "$( grep -E '^[5-9]' <<< $gccVersion)" ];then
		gccVersion=$(grep -Eo '^[5-9]' <<< $gccVersion )
	fi
	local ubgv="/usr/bin/gcc-$gccVersion"

	if [ -z "$( check_package_status 'module-assistant' 'i' )" ];then
		install_package 'module-assistant'
	fi
	if [ -z "$( check_package_status 'build-essential' 'i' )" ];then
		install_package 'build-essential'
	fi

	if [ -x "$ubgv" ];then
		# the correct g++ version is required for the gcc version to build module
		if [ ! -x "/usr/bin/g++-$gccVersion" -a -n "$( check_package_status "g++-$gccVersion" 'c' )" ];then
			install_package "g++-$gccVersion"
		fi
		export CC=$ubgv
	else
		
		# going to try to update gcc to kernel version first before error exit.
		if [ -n "$( check_package_status "gcc-$gccVersion" 'c' )" ];then
			install_package "gcc-$gccVersion"
			if [ "$( check_package_status "g++-$gccVersion" 'c' )" ];then
				install_package "g++-$gccVersion"
			fi
			export CC=$ubgv
		else
			error_handler 250 "$ubgv"
		fi
	fi
	eval $LOGPE
}

check_apt_aptitude()
{
	eval $LOGUS
	local opt='' managers='apt-get aptitude quit'
	local aptPref=$( get_set_prefs 'get' 'apt-type' | cut -d '=' -f 2 | grep -E  '^(apt-get|aptitude)$' )

	if [ -f /var/log/aptitude ];then
		if [ -z "$aptPref" ];then
			echo $LINE
			echo "${S}It appears you are using aptitude. It is not good to mix apt-get and aptitude."
			echo "Please pick your preferred package manager before you continue, or exit now."
			echo
			echo "Your selection (for example: ${C}apt-type=apt-get${S}) will be stored in ${C}/etc/smxi.conf${S}"
			echo "${C}smxi${S} will also use this choice for its default package manager, so make sure it's correct."
			echo $LINE

			select opt in $managers
			do
				case $opt in
					apt-get|aptitude)
						APT_TYPE=$opt
						log_function_data "Selected package manager: $opt"
						get_set_prefs 'set' "apt-type=$opt"
						;;
					quit)
						echo "${S}Ok, figure it out and try again later...${N}"
						exit 0
						;;
					*)
						echo "${E}You have to pick one before you can continue!${N}"
						ask_apt_aptitude
						;;
				esac
				break
			done
		else # set apt type
			APT_TYPE=$aptPref
		fi
		log_function_data "APT_TYPE: $APT_TYPE"
		case $APT_TYPE in
			aptitude)
				WITHOUT_RECOMMENDS='--without-recommends'
				;;
			apt-get)
				WITHOUT_RECOMMENDS='--no-install-recommends'
				;;
		esac
	fi
	eval $LOGUE
}

# args: $1 - get/set; $2 - prefname
get_set_prefs()
{
	eval $LOGUS
	local etcsm='/etc/smxi.conf' retValue='' name='' value=''

	case $1 in
		get)
			retValue=$( grep -s $2 $etcsm )
			echo $retValue
			log_function_data "Return value: $retValue"
			;;
		set)
			touch $etcsm
			# test = first, this will handle the base name and anything else
			name=$( cut -d '=' -f 1 <<< $2 )
			# check to see if it's there, if it is, it must be a = type thing
			if [ -z "$( grep -s $name $etcsm )" ];then
				echo $2 >> $etcsm
				log_function_data "Added $2 to $etcsm"
			else
				sed -i "s/$name.*/$2/" $etcsm
				log_function_data "Updated $name to $2 in $etcsm"
			fi
			;;
	esac
	eval $LOGUE
}

# Returns null if package is not available in user system apt.
# args: $1 - package to test; $2 c/i
check_package_status()
{
	eval $LOGUS
	local packageVersion='' statusType='' cacheData=''
	local poolPackageCount=0

	case $2 in
		c)	statusType='Candidate:'
			;;
		i)	statusType='Installed:'
			;;
	esac

	LC_ALL= LC_CTYPE= LC_MESSAGES= LANG= cacheData="$( apt-cache policy $1 2>/dev/null )"
	
	# we need to filter out all cases were the only instance in apt is the locally installed
	# version, ie:  *** 2.13 0 \ 100 /var/lib/dpkg/status is the only value returned
	poolPackageCount=$( grep -Es "^[[:space:]]*[0-9]{3}"  <<< "$cacheData" | grep -vcE "^[[:space:]]*100[[:space:]]" )
	
	packageVersion=$( awk '
	/'$statusType'/ && !/\((None|none)\)/ {print $2}' <<< "$cacheData" )
	
	# if either none found, or only a local apt version available, return null
	if [ "$statusType" == 'Candidate:' -a "$poolPackageCount" -eq 0 ];then
		packageVersion=''
	fi

	echo $packageVersion
	log_function_data "Package Version: $packageVersion"
	eval $LOGUE
}

# arg: $1 - package names
install_package()
{
	eval $LOGUS
	local useUntrusted='--allow-unauthenticated' install='install' doYes='-y'
	local returnValue=0
	
	if [ "$UPDATED" != 'true' ];then
		echo "${S}Running $APT_TYPE update now...${N}"
		$APT_TYPE update && UPDATED='true'
	fi
	if [ "$APT_TYPE" == 'aptitude' ];then
		if [ "$SYSTEM_BASE" == 'etch' ];then
			useUntrusted='' # etch aptitude doesn't support this
		else
			useUntrusted='--allow-untrusted'
		fi
		doYes=''
	fi
	log_function_data "WITHOUT_RECOMMENDS: $WITHOUT_RECOMMENDS"
	if  [ -n "$1" ];then
		echo "${S}Installing required package ${C}$1${S} now...${N}"
		$APT_TYPE install $WITHOUT_RECOMMENDS $useUntrusted $doYes $1 || error_handler 200 $1
		returnValue="$?"
	fi
	eval $LOGUE
	return $returnValue
}

# args: $1 - package list to remove; $2 - remove-all/loop
remove_package()
{
	eval $LOGUS
	local response='' package='' returnValue=0

	if [ -n "$1" ];then
		case $2 in
			# this remove list is already calculated so no need to check it again
			remove-all)
				echo $MLINE
				echo "${M}Removing the following package(s): "
				echo "${C}$1"
				echo $MLINE
				$APT_TYPE purge $1 || error_handler 196 "$1"
				;;
			loop)
				echo $MLINE
				echo "${M}You will need to remove the following package(s): ${C}$1"
				echo "${M}in order to proceed with your install.${N}"
				echo $MLINE
				for package in $1
				do
					if [ -n "$( dpkg -l | grep $package )" ];then
						echo "${S}Removing ${C}$package${S}...${N}"
						$APT_TYPE purge $package || error_handler 196 "$package"
					else
						echo "${S}The package ${C}$package${S} is not installed, continuing...${N}"
					fi
				done
				echo "${S}Package(s) removed successfully, continuing with driver install.${N}"
				;;
		esac
	fi
	eval $LOGUE
}

test_package_available()
{
	eval $LOGUS
	local packageAvailable=''

	LC_ALL= LC_CTYPE= LC_MESSAGES= LANG= packageAvailable=$( apt-cache policy $1 2>/dev/null | grep -i 'Candidate:' | cut -d ':' -f 2-4 | cut -d ' ' -f2 | grep -iv '(none)' )

	log_function_data "packageAvailable: $packageAvailable"
	echo $packageAvailable
	eval $LOGUE
}

# args: $1 script to get/check; $2 - which download source to use
# $3 - extra message; $4 - repeat, to only retest download failure once
check_update_script()
{
	local fileNameTemp="$( mktemp -p $SCRIPT_HOME/ $1.XXXXXXXXXX )"
	local isGood='' downloadUrl=$2 extraText='' uArgs='up' ua="-U s-tools/$SCRIPT_NAME"

	if [ -n "$( grep -E '(dev|svn|alt)' <<< $3 )" ];then
		extraText="${C}$3:\n$2${S}"
	else
		extraText="${C}$3${S}"
	fi

	cd $SCRIPT_HOME # make sure we're in the right place

	if [ -f "$fileNameTemp" ];then
		rm -f $fileNameTemp # remove the temp file, should never fire, but why not?
	fi

	# if newer version, download / replace lib file
	if [ "$1" == "$SCRIPT_NAME" ];then
		if [ "$FORCE_UPDATE" == 'true' -o "$4" == 'repeat' ];then
			uArgs='ufr'
		fi
		ua="$ua.$uArgs"
		echo -e "${S}Updating ${C}$SCRIPT_NAME${S} now using the $extraText${N}"
		wget $ua -q -O$fileNameTemp $downloadUrl$1 || error_handler 198 $2$1
		# all smxi files have this string as last line, so if it's there, the file should usually
		# run fine, except for weird fringe cases where the ascii file is corrupted partially
		isGood=$( grep '##\*\*EOF\*\*##' $fileNameTemp )

		if [ -n "$isGood" ];then
			mv -f $fileNameTemp $1
			chmod 705 $1
			if [ "$FORCE_UPDATE" != 'true' ];then
				./$1 -R$START_OPTIONS
			else
				print_information
				echo "${C}$SCRIPT_NAME${B} was successfully updated. Please start the script again"
				echo "to access the latest features and drivers. Exiting now.${N}"
			fi
			exit 0
		else
			# dump the bad file
			rm -f $fileNameTemp

			if [ "$4" != 'repeat' ];then
				# let's try this once again to make sure it wasn't just a temp problem
				echo -e "${E}The file ${C}$1${E} did not download correctly from:\n$2\nRetrying download now...${N}"
				check_update_script "$1" "$2" "$3" 'repeat'
			else
				error_handler 248 $1
			fi
		fi
	# I'm only going to load this stuff one time per file so I won't
	# have to worry about rechecking and multi downloads etc
	fi
}

print_information()
{
	eval $LOGPS
	local scriptVersion=$( grep -Eo -m 1 "(version:).*" $SCRIPT_HOME/$SCRIPT_NAME | cut -d ' ' -f 2 )
	#echo 'sv:' $scriptVersion
	local scriptDate=$( grep -Eo -m 1 '(Date:).*' $SCRIPT_HOME/$SCRIPT_NAME | cut -d ' ' -f 2-4 )
	local vmPlayer=''
	if [ -e /usr/bin/vmplayer ];then
		# vmPV=$( vmplayer -v )
		vmPlayer='echo "VM installed: '$vmPV'"'
	fi
	#local cardInfo=$( lspci | gawk -F': ' '/VGA compatible controller.*: / { print $NF }' | sed -r 's%(ATI\sTechnologies\sInc\s|nVidia\sCorporation\s)(.*)%\2%'  )
	local vmInfo=''

	echo $MLINE
	echo " ${M}$SCRIPT_NAME${S} :: version: ${C}$scriptVersion${S} :: last updated: ${C}$scriptDate${N}"
	#eval $vmPlayer
	eval $LOGPE
}

print_quit()
{
	echo "${S}Thanks for checking out the Virtual Machine Installer.${N}"
	exit 0
}

# this is the hit enter to continue blurb...
print_hec()
{
	local response=''

	if [ "$AUTORUN" != 'true' ];then
		echo $LINE
		# halt the script so people can read the advice
		echo $HEC
		echo $LINE
		read response
	fi
}

# this handles typos for y/n questions, or wrong case
print_error()
{
	echo $EBAR
	if [ "$1" == "yn" ];then
		echo "${E}You must enter ${C}y${E} to run this option, or ${C}n${E} to reject it."
		echo "Please make sure that you enter either ${C}y${E} or ${C}n${E}, lower case, thanks.${N}"
	elif [ "$1" == "opt" ];then
		echo "${E}======= Error: please enter one of the numbers in the list =======${N}"
	fi
	echo $EBAR
}

create_log()
{
	local svmiVersion=$( grep 'version:' $SCRIPT_NAME | grep -o "[0-9]*\.[0-9]*\.[0-9]*" )

	if [ ! -f $SCRIPT_ROTATE ];then
		echo "$LOG_FILE {
	rotate 1
	size 100k
	create
}
" > $SCRIPT_ROTATE
	fi
	touch $LOG_FILE # make sure there's one there for rotate to look at
	if [ -n "$( which logrotate )" ];then
		logrotate $SCRIPT_ROTATE
	fi
	touch $LOG_FILE # and if rotated, need a new one
	echo "=========================================================" >> $LOG_FILE
	echo "START $SCRIPT_NAME LOGGING:" >> $LOG_FILE
	echo "=========================================================" >> $LOG_FILE
	echo "Script started: $( date +%Y-%m-%d-%H:%M:%S )" >> $LOG_FILE
	echo "Installed Kernel: $KERNEL_FULL" >> $LOG_FILE
	echo "$SCRIPT_NAME script version: $svmiVersion" >> $LOG_FILE
	echo "$SCRIPT_NAME start options: $START_OPTIONS" >> $LOG_FILE
	echo "SYSTEM_BASE: $SYSTEM_BASE" >> $LOG_FILE
	echo "=========================================================" >> $LOG_FILE
	# it's important to log these in case there's some issue or bug in the values
	if [ -f $SM_VALUES ];then
		log_function_data "Begin User Set $SM_VALUES:\n$( cat $SM_VALUES)\nEnd User Set Values"
	fi

	LOGGING_STARTED='true'
}

# $1 type or data; $2 is function; $3 - function args, optional
log_function_data()
{
	local funcInfo='' logSpacer='  '

	case $1 in
		ps)
			funcInfo="Function: $2 - Primary: Start"
			;;
		pe)
			funcInfo="Function: $2 - Primary: End"
			;;
		us)
			funcInfo="Function: $2 - Utility: Start"
			;;
		ue)
			funcInfo="Function: $2 - Utility: End"
			;;
	esac

	if [ -n "$funcInfo" ];then
		log_writer "$funcInfo"
	else
		log_writer "${logSpacer}$1"
	fi

	if [ -n "$3" ];then
		log_writer "${logSpacer}Args: $3"
	fi
}

# args: $1 - data to write to logfile. Note that the function is always logged
# via function_logging first, and other relevant globals are set there as well
log_writer()
{
	# this handles first line indents, all other indents must be set in message data
	# like so: message="some problem... \n${LOG_INDENT}more problem stuff..."
	if [ "$LOGGING_STARTED" == 'true' ];then
		# strip out escape color code, if any. Method by dzz of sidux, thanks ;-)
		echo -e "$1" | sed 's/\x1b\[[0-9]\{1,2\}\(;[0-9]\{1,2\}\)\{0,2\}m//g' >> $LOG_FILE
	fi
}

########################################################################
#### Core virtual machine installer functions
#### -------------------------------------------------------------------

# startup questions, users choose vm and action
vm_main_selector()
{
	eval $LOGPS
	local repeat='' options='' opt='' quitContinue='quit'
	# testing for both ose and non ose versions, then installing the requested version
	if [ "$SM_INSTALL" == 'true' ];then
		quitContinue='return-to-smxi'
	fi

	echo $MLINE
	echo "${M} Virtual Machine Options"

	echo $MLINE
	echo "${S}For most new or average users, ${C}VirtualBox${S} is a simple, clean install,"
	echo "and you'll have your vbox up and running almost immediately."
	echo $LINE
	echo "${C}Vmware${S} options are basic, and only support vmware player."

	echo $LINE
	echo "${S}For convenience, this top level menu also includes the options to"
	echo "rebuild vmware/vbox kernel modules if that's all you need to do."
	echo $LINE
	echo "${C}1${S} - ${C}virtualbox-options${S} Downloads, installs, rebuild kernel module, ${C}vbox tools${S}, for"
	echo "    both ${C}virtualbox non-ose${S} and ${C}virtualbox-ose${S}. Current: ${C}non-ose $VBOX_VERSION${S}."
	echo "${C}2${S} - ${C}vmware-options${S} Downloads, installs, rebuild kernel module, and a few other things."

	echo $LINE

	echo "${C}3${S} - ${C}build-vbox-module-ose${S} Installs vbox OSE module, updates modules."
	echo "    ${M}NOTE: System must be fully dist-upgraded for this to work right before you run this!"
	echo "${C}4${S} - ${C}build-vbox-module-non-ose${S} Will rebuild existing virtualbox non ose kernel module."
	echo "${C}5${S} - ${C}build-vmplayer-module${S} Rebuilds vmplayer kernel module. Requires vmplayer v. 2.5.x or greater."

	echo $LINE
	echo "${C}6${S} - ${C}$quitContinue${S}"

	echo $LINE
	echo -e $SLE
	echo $LINE

	options="virtualbox-options vmware-options build-vbox-module-ose build-vbox-module-non-ose build-vmplayer-module $quitContinue"
	select opt in $options
	do
		case $opt in
			virtualbox-options)
				vbox_main_selector
				repeat='true'
				;;
			vmware-options)
				vmware_main_selector
				repeat='true'
				;;
			build-vbox-module-ose)
				install_vbox_module ose
				repeat='true'
				;;
			build-vbox-module-non-ose)
				install_vbox_module non-ose
				repeat='true'
				;;
			build-vmplayer-module)
				vmware_module_builder
				repeat='true'
				;;
			$quitContinue)
				print_quit
				;;
			*)
				print_error opt
				repeat='true'
				;;
		esac
		break
	done

	if [ "$repeat" == 'true' ];then
		vm_main_selector
	fi
	eval $LOGPE
}

# vbox install/update options
vbox_main_selector()
{
	eval $LOGPS
	local repeat='' options='' opt='' quitContinue='quit' vboxInstalled='None Detected'
	# testing for both ose and non ose versions, then installing the requested version
	get_vbox_installed_version
	if [ -n "$VBOX_INSTALLED_VERSION" ];then
		vboxInstalled=$VBOX_INSTALLED_VERSION
	fi
	if [ "$SM_INSTALL" == 'true' ];then
		quitContinue='return-to-smxi'
	fi

	echo $MLINE
	echo "${M} VirtualBox Install/Module Options"

	echo $MLINE
	echo "${S}To install other vbox non-ose/vmware versions, use the ${C}svmi -V <vbox/vmware version>${S} option"

	echo $MLINE
	echo "${C}1${S} - ${C}install-vbox-ose${S} Installs virtualbox-ose. If you need to update modules after installing,"
	echo "    please run ${C}build-vbox-module-ose${S} as well."
	echo "${C}2${S} - ${C}build-vbox-module-ose${S} Installs vbox OSE module, updates modules,"
	echo "    adds module to $EMOD if required."
	echo "    ${M}NOTE: System must be fully dist-upgraded for this to work right before you run this!"

	echo $LINE
	echo "${S}vbox non-ose default install version: ${C}$VBOX_VERSION${S}"
	echo "Available vbox non-ose versions: ${C}$VBOX_VERSIONS"
	echo "${S}Note: ${C}Vbox-non-ose versions 4${S} or newer will also install ${C}VirtualBox Extension Pack"
	echo "Also, as of ${C}4.1.6${S}, there is no ${C}Lenny${S} support, so I have removed that option."
	echo $LINE
	echo "${C}3${S} - ${C}install-vbox-non-ose-squeeze${S} Installs the ${C}Debian Squeeze${S} vbox deb."
	echo "    Module is built automatically."
	echo "${C}4${S} - ${C}install-vbox-non-ose-wheezy${S} Installs the ${C}Debian Wheezy/Sid${S} vbox deb."
	echo "    Module is built automatically (${M}vbox-non-ose 1.6.6 or higher only${S})."
	echo "${C}5${S} - ${C}build-vbox-module-non-ose${S} Will rebuild existing virtualbox non ose kernel module."
	echo $LINE
	echo "${C}6${S} - ${C}install-vbox-addons${S} Downloads vbox guest additions iso. Helps with driver installation,"
	echo "    For both ose and non-ose. Highly recommended. Will download the version (${C}>1.6.0${S})"
	echo "    for your currently installed virtualbox version: ${C}$vboxInstalled"

	echo $LINE
	echo "${C}7${S} - ${C}uninstall-vbox${S} Removes all currently installed ${C}VirtualBox${S} components."

	echo "${C}8${S} - ${C}return-to-main-menu${S} Return to the main ${C}$SCRIPT_NAME${S} selector menu (${C}vmware${S} or ${C}vbox${S})"
	echo "${C}9${S} - ${C}$quitContinue${S}"

	echo $LINE
	echo -e $SLE
	echo $LINE

	options="install-vbox-ose build-vbox-module-ose install-vbox-non-ose-squeeze install-vbox-non-ose-wheezy build-vbox-module-non-ose install-vbox-addons uninstall-vbox return-to-main-menu $quitContinue"
	select opt in $options
	do
		case $opt in
			install-vbox-ose)
				install_vbox ose
				repeat='true'
				;;
			build-vbox-module-ose)
				install_vbox_module ose
				repeat='true'
				;;
			install-vbox-non-ose-squeeze)
				install_vbox 'non-ose' 'squeeze'
				repeat='true'
				;;
			install-vbox-non-ose-wheezy)
				install_vbox 'non-ose' 'wheezy'
				repeat='true'
				;;
			build-vbox-module-non-ose)
				install_vbox_module non-ose
				repeat='true'
				;;
			install-vbox-addons)
				install_vbox_addons
				repeat='true'
				;;
			uninstall-vbox)
				uninstall_vm_app 'vbox'
				repeat='true'
				;;
			return-to-main-menu)
				:
				;;
			$quitContinue)
				print_quit
				;;
			*)
				print_error opt
				repeat='true'
				;;
		esac
		break
	done

	if [ "$repeat" == 'true' ];then
		vbox_main_selector
	fi
	eval $LOGPE
}

# vmware options
vmware_main_selector()
{
	eval $LOGPS
	local repeat='' options='' opt='' quitContinue='quit'
	# testing for both ose and non ose versions, then installing the requested version

	if [ "$SM_INSTALL" == 'true' ];then
		quitContinue='return-to-smxi'
	fi

	echo $MLINE
	echo "${M} Vmware Install/Module Options"

	echo $MLINE
	echo "${S}vmware options are basic, and only support vmware player. To build your vmx files, and the"
	echo "vmdk images if you don't know how to do that, please use this site: ${C}www.easyvmx.com"
	echo
	echo "${S}As of VMPlayer 3.0, $SCRIPT_NAME cannot download and install it because Vmware shutdown."
	echo "direct downloads. You have to fill in a form to get it, but $SCRIPT_NAME can still rebuild"
	echo "the kernel modules as usual. You need vmplayer 3.0 or newer for it to run on new kernels."
	echo
	echo "${S}As of VMPlayer 2.5.0, the any any patch is no longer needed."
	echo "I'm leaving any-any options for people with 2.0.5 or older vmware installs for now."
	echo $LINE
	echo "${S}Vmware player version to install: ${C}$VMPLAYER_NUMBER${S}"
	echo "any-any patch version (only for old vmware installs): ${C}$ANYANY_NUMBER$ANYANY_ALT"
	echo $LINE
	echo "${C}1${S} - ${C}install-vmware${S} Downloads, installs, and runs vmware player (+ patches if needed)."
	echo "${C}2${S} - ${C}build-vmplayer-module${S} Rebuilds vmplayer kernel module. Requires vmplayer v. 2.5.x or greater."
	echo "${C}3${S} - ${C}run-anyany${S} Runs any-any, downloads and installs if required (legacy)."
	echo "${C}4${S} - ${C}install-qemu${S} Installs qemu if required. ${M}NEW: great site to make your"
	echo "    vmdk/vmx files, super easy, make a note of it. Highly recommended: ${C}www.easyvmx.com"

	echo $LINE
	echo "${C}5${S} - ${C}uninstall-vmware${S} Removes all currently installed ${C}Vmware${S} components."
	echo "${C}6${S} - ${C}return-to-main-menu${S} Return to the main ${C}$SCRIPT_NAME${S} selector menu (${C}vmware${S} or ${C}vbox${S})"
	echo "${C}7${S} - ${C}$quitContinue${S}"

	echo $LINE
	echo -e $SLE
	echo $LINE

	options="install-vmware build-vmplayer-module run-anyany make-qemu-image uninstall-vmware return-to-main-menu $quitContinue"
	select opt in $options
	do
		case $opt in
			install-vmware)
				install_vmware $VMP
				repeat='true'
				;;
			build-vmplayer-module)
				vmware_module_builder
				repeat='true'
				;;
			run-anyany)
				install_vmware $AA
				repeat='true'
				;;
			make-qemu-image)
				create_qemu_image
				repeat='true'
				;;
			uninstall-vmware)
				uninstall_vm_app 'vmplayer'
				repeat='true'
				;;
			return-to-main-menu)
				:
				;;
			$quitContinue)
				print_quit
				;;
			*)
				print_error opt
				repeat='true'
				;;
		esac
		break
	done

	if [ "$repeat" == 'true' ];then
		vmware_main_selector
	fi
	eval $LOGPE
}

vmware_module_builder()
{
	eval $LOGUS
	calculate_vmplayer_number
	apply_module_fixes 'vmplayer'
	if [ -n "$VMPLAYER_INSTALLED" ];then
		build_vmware_module
	else
		error_handler 185
	fi
	eval $LOGUE
}

# args: $1 - type vbox/vmplayer
uninstall_vm_app()
{
	eval $LOGUS
	local returnValue=0 repeat='' yesOpt='' yesText=''
	local vmPlayerRemove='vmware-uninstall' vmTest=''
	local evm='/etc/vmware'
	local ulv='/usr/lib/vmware'

	case $1 in
		vbox)
			yesOpt='yes-remove-virtualbox'
			yesText='VirtualBox'
			vmTest=$( dpkg -l | awk '{print $2}' | grep -i virtualbox )
			;;
		vmplayer)
			yesOpt='yes-remove-vmware'
			yesText='Vmware'
			vmTest=$( which vmware-uninstall )
			;;
	esac
	log_function_data "Remover: $vmTest"
	if [ -n "$vmTest" ];then
		echo $MLINE
		echo "$SPACER${M}Virtual Machine Remover"
		echo $MLINE
		echo "${S}If you select ${C}1${S}, you will remove the virtual machine software, but the"
		echo "machine images, if any, will remain. If you decide to reinstall later, you can reuse them."
		echo $LINE

		echo "${C}1 - $yesOpt${S} - Remove ${C}$yesText${S}. This removes all components of ${C}$yesText${S} completely."
		echo "${C}2 - no-return-to-menu${S} - Don't uninstall ${C}$yesText${S} after all."
		echo $LINE
		echo -e $SLE
		echo $LINE
		options="$yesOpt no-return-to-menu"
		select opt in $options
		do
			log_function_data "opt selected: $opt"
			case $opt in
				$yesOpt)
					case $1 in
						vbox)
							remove_package "$vmTest" 'remove-all'
							;;
						vmplayer)
							exec $vmTest
							# this is required to avoid an annoying bug with corrupted
							# vmware database on reinstall or upgrade. I'm going to leave
							# this for now as only uninstall, but it might make sense to also
							# do this for every upgrade, I'll see how the bugs go.
							# http://techpatterns.com/forums/about1188.html
							if [ -d $evm ];then
								rm -rf $evm
								echo "${S}Removed $evm to avoid future issues.${N}"
							fi
							if [ -d $ulv ];then
								rm -rf $ulv
								echo "${S}Removed $ulv to avoid future issues.${N}"
							fi
							;;
					esac
					returnValue=$?
					;;
				no-return-to-menu)
					returnValue=1
					;;
				*)
					print_error opt
					repeat='true'
					;;
			esac
			break
		done

		log_function_data "Return Value: $returnValue"

		eval $LOGUE
		if [ "$repeat" == 'true' ];then
			uninstall_vm_app "$1"
		fi
	else
		echo "${M}You do not appear to have any ${C}$yesText${M} components installed.${N}"
		print_hec
	fi
}
### -------------------------------------------------------------------
### vmware functions
### -------------------------------------------------------------------

calculate_vmplayer_number()
{
	eval $LOGUS
	echo $LINE
	echo -n "${S}Calculating installed ${C}vmplayer${S} number...  ${N}"
	# vmware-player          3.1.0.261024

	VMPLAYER_INSTALLED=$( vmware-installer -l 2>/dev/null | grep 'vmware-player' | awk '{print $2}' | cut -d '.' -f 1-3 )
	if [ -n "$VMPLAYER_INSTALLED" ];then
		echo "${S}Version: ${C}$VMPLAYER_INSTALLED${N}"
	else
		echo "${W}No installed version detected${N}"
	fi
	log_function_data "$VMPLAYER_INSTALLED"
	eval $LOGUE
}

construct_file_name()
{
	eval $LOGUS

	if [ "$INSTALL_TYPE" == "$AA" ];then
		# this will try the next sequence of number in case he updates it
		if [ "$1" == 'failed' ];then
			ANYANY_NUMBER=$(( $ANYANY_NUMBER + 1 ))
		fi

		DIR_NAME=$ANYANY_VERSION$ANYANY_NUMBER$ANYANY_ALT # handles 'a' for 2.6.24
		FILE_NAME=$ANYANY_VERSION$ANYANY_FILE_DASH$ANYANY_NUMBER$ANYANY_ALT$ANYANY_Z
		FILE_URL=$ANYANY_PREFIX$FILE_NAME
	elif  [ "$INSTALL_TYPE" == "$VMP" ];then
		DIR_NAME=$VMPLAYER_VERSION$VMWARE_32_64
		FILE_NAME=$DIR_NAME$VMWARE_Z
		FILE_URL=$VMPLAYER_PREFIX$FILE_NAME
	fi

	log_function_data "DIR_NAME: $DIR_NAME"
	log_function_data "FILE_NAME: $FILE_NAME"
	log_function_data "FILE_URL: $FILE_URL"
	eval $LOGUE
}
# construct_file_name anyany failed; exit

# test, download, run app
download_file()
{
	eval $LOGUS
	local noGood='' fileURL='' testExtract=''

	if [ ! -d "$VMWARE_INSTALL_PATH" ];then
		mkdir $VMWARE_INSTALL_PATH
	fi

	cd $VMWARE_INSTALL_PATH
	#echo 'pwd is: ' $(pwd);exit
	if [ ! -d "$DIR_NAME" ];then
		if [ "$DOWNLOAD_COUNTER" -le 1 ];then
			wget -Nc -T $TIME_OUT $FILE_URL || noGood='true'

			if [ "$noGood" == 'true' ];then
				if [ "$INSTALL_TYPE" == "$AA" ];then
					DOWNLOAD_COUNTER=$(( $DOWNLOAD_COUNTER + 1 ))
					construct_file_name failed
					download_file
				else
					error_handler 195 $FILE_URL
				fi
			else
				log_function_data "Send FILE_URL to test_extract_file: $FILE_URL"
				testExtract='true'
			fi
		else
			error_handler 194 $FILE_URL
		fi
	else
		echo "${M}You have already downloaded the package, proceeding with install now...${N}"
		testExtract='true'
	fi
	# don't extract for new bundle syntax stuff
	if [ "$testExtract" == 'true' ];then
		test_extract_file
	fi
	eval $LOGUE
}

test_extract_file()
{
	eval $LOGUS
	local extractFailed=''

	if [ ! -d "$DIR_NAME" ];then
		if [ -z "$( grep '.bundle$' <<< $FILE_NAME )" ];then
			tar xzf $FILE_NAME || error_handler 193 $FILE_NAME
		else
			mkdir $DIR_NAME
			mv $FILE_NAME $DIR_NAME
		fi
	fi

	if [ -d "$VMPLAYER_DIR" -a "$INSTALL_TYPE" == "$VMP" ];then
		mv $VMPLAYER_DIR $DIR_NAME
	fi

	eval $LOGUE
}

run_file()
{
	eval $LOGUS
	local runFile=''

	cd $DIR_NAME

	case $INSTALL_TYPE in
		$AA)
			runFile=$ANYANY_RUN
			;;
		$VMP)
			if [ -z "$( grep '.bundle$' <<< $FILE_NAME )" ];then
				runFile=$VMPLAYER_RUN
			else
				runFile=$FILE_NAME
			fi
			;;
	esac

	sh ./$runFile
	eval $LOGUE
}

# $1 which install type to use
install_vmware()
{
	eval $LOGPS
	INSTALL_TYPE=$1

	echo $LINE

	if [ "$1" == "$AA" ];then
		install_anyany
	elif [ "$1" == "$VMP" ];then
		construct_file_name
		if [ -z "$( grep '.bundle$' <<< $FILE_NAME )" ];then
			echo "${S}Starting $VMP install and setup. When vmware setup asks you this question:"
			echo "${M}Before running VMware Player for the first time, you need to configure it"
			echo "by invoking the following command: /usr/bin/vmware-config.pl...."
			echo
			echo "${S}Answer 'n' to this question, and then $AA setup and install will begin automatically.${N}"
		else
			echo "${S}Starting $VMP install and setup now using the new ${C}.bundle${S} file installer...${N}"
		fi
		print_hec
		# this fixes a possible bug in running vmplayer
		if [ -z "$( check_package_status 'shared-mime-info' 'i' )" ];then
			install_package 'shared-mime-info'
		fi
		download_file
		run_file
		if [ -z "$( grep '.bundle$' <<< $FILE_NAME )" ];then
			# for vmp tar.gz, we want to also run any any
			INSTALL_TYPE=$AA
			install_anyany
			run_file
		fi
		apply_fixes_post_install 'vmplayer'
		if [ -n "$( grep '.bundle$' <<< $FILE_NAME )" ];then
			build_vmware_module
		fi
	fi

	eval $LOGPE
	print_hec
}

build_vmware_module()
{
	eval $LOGUS
	local errorReturn='' vmMod='vmware-modconfig'
	local vmModConf=$( which $vmMod )
	
	if [ -n "$vmModConf" -a -x "$vmModConf" ];then
		echo $LINE
		echo "${S}Building Vmware module for your ${C}$KERNEL_FULL${S} kernel now...${N}"
		vmware-modconfig --console --install-all 
		errorReturn=$?
		log_function_data "vmware-modconfig returned: $errorReturn"
		if [ "$errorReturn" -eq 0 ];then
			echo "${S}Vmplayer kernel module built successfully. All done!${N}"
		else
			echo "${W}ERROR: ${C}$errorReturn${W} occurred in the Vmplayer kernel module build!${N}"
		fi
	else
		echo $WLINE
		echo "${W}You do not have the required vmplayer tool: ${C}$vmMod"
		echo "${S}Unable to build your kernel module. You probably are using vmplayer 2.0.x or haven't"
		echo "installed vmplayer. Please correct this issue.${N}"
		print_hec
	fi
	eval $LOGUE
}

install_anyany()
{
	eval $LOGUS
	if [ -x "$VMWARE_CONFIG" ];then
		echo "${S}Starting $AA install and setup. When any any asks if you want to run"
		echo "/usr/bin/vmware-config.pl answer 'y' and your vmware install will complete.${N}"
		print_hec
		construct_file_name
		download_file
	else
		error_handler 192
	fi
	eval $LOGUE
}

create_qemu_image()
{
	eval $LOGUS
	local qemuExists=$( check_package_status 'qemu' 'i' )

	echo $LINE
	if [ -z "$qemuExists" ];then
		install_package qemu
	else
		echo "${C}qemu${M} is already installed on your system.${N}"
	fi

	eval $LOGUE
	print_hec
}

### -------------------------------------------------------------------
### vbox functions
### -------------------------------------------------------------------

get_vbox_installed_version()
{
	eval $LOGUS
	
	# this should handle virtualbox-2.0-ose; virtualbox-ose; virtualbox-3.0
	# slice out name and version number
	local workingVbox=$( dpkg -l | grep -E 'virtualbox-(ose|[0-9]\.[0-9]-ose|[0-9]\.[0-9])[[:space:]]' | awk '{print $2 " " $3}' )
	
	if [ -z "$workingVbox" ];then
		: # do nothing, leave unset for other error handling
	elif [ "$( wc -w <<< $workingVbox )" -eq 2 ];then
		VBOX_INSTALLED_VERSION=$( echo $workingVbox | awk '{print $2}' | cut -d '-' -f 1 )
		APT_VBOX_VERSION_NU=$( echo $workingVbox | awk '{print $1}' | grep -Eo '\-[0-9]+\.[0-9]+' )
	else
		error_handler 187 "$workingVbox"
	fi

	log_function_data "workingVbox: $workingVbox\nVBOX_INSTALLED_VERSION: $VBOX_INSTALLED_VERSION :: APT_VBOX_VERSION_NU: $APT_VBOX_VERSION_NU"
	
	eval $LOGUE
}

# create and install vbox module:
# $1 is ose/non-ose; $2 - lenny/squeeze/wheezy + whatever new versions come
install_vbox()
{
	eval $LOGPS
	local vboxOSE="virtualbox-ose virtualbox-ose-source"
	local vboxGeneral=$( dpkg -l | cut -d ' ' -f 3 | grep 'virtualbox' )
	local vboxBad='virtualbox virtualbox-source'
	local vboxOseVersion=''
	# default to ose install
	local toInstall="$vboxOSE" toRemove="$vboxBad $vboxGeneral"
	local returnValue=0
	
	if [ -n "$( test_package_available 'virtualbox-2.0-ose' )" ];then
		vboxOSE='virtualbox-2.0-ose virtualbox-2.0-ose-source'
	fi

	if [ "$1" == 'non-ose' ];then
		toRemove=$vboxGeneral
		# old dependencies:
		#toInstall='libicu38 libxalan110'
		# libqtcore4 libqtgui4
		if [ "$APT_TYPE" == 'apt-get' ];then
			toInstall='libidl0 adduser'
			if [ -n "$( grep -E '^[2-6]\.' <<< $VBOX_VERSION )" ];then
				toInstall="$toInstall libqtcore4 libqtgui4"
			fi
		else
			toInstall=''
		fi
	fi
	log_function_data "To remove: $toRemove"
	log_function_data "To install: $toInstall"
	
	if [ -n "$( ps aux | grep -is 'virtualbox' | grep -v 'grep' )"  ];then
		error_handler 246
	fi
	if [ "$B_SKIP_FUNCTION" != 'true' ];then
		remove_package "$toRemove" 'loop'
		install_package "$toInstall"
	fi
	
	case $1 in
		# cram in the qt stuff that's required for display if missing, 
		# or use vboxgtk but that requires more testing.
		ose)
			# test after update not before
			vboxOseVersion=$( check_package_status 'virtualbox-ose' 'i' | cut -d '.' -f 1-2 )
			if [ -n "$( grep -Ei '^(2\.[2-9]|[3-4])' <<< $vboxOseVersion )" ];then
				if [ -n "$( check_package_status 'virtualbox-ose-qt' 'c' )" -a -z "$( check_package_status 'virtualbox-ose-qt' 'i' )" ];then
					install_package "virtualbox-ose-qt"
				fi
			fi
			;;
		non-ose)
			install_vbox_non_ose "$2" || returnValue=$?
			;;
	esac
	log_function_data "returnValue: $returnValue"
	if [ "$returnValue" -eq 0 ];then
		add_vbox_user
	else
		echo "${M}Unable to complete the vbox install process due to errors.${N}"
	fi

	eval $LOGPE
	print_hec
}

# args: $1 - squeeze/lenny
install_vbox_non_ose()
{
	eval $LOGPS
	local arch='i386' installError=0 downloadError=0 returnValue=0
	local vboxVersionNu=''
	if [ "$BITS" == '64' ];then
		arch='amd64'
	fi
	# set to null for 1.x.x versions
	if [ -n "$( grep -E '^[2-6]\.' <<< $VBOX_VERSION )" ];then
		vboxVersionNu="-$( grep -Eo '^[2-6]\.[0-9]' <<< $VBOX_VERSION )"
	fi
	local vboxVersion=''
	local vboxName='virtualbox'$vboxVersionNu
	local debName=$vboxName'_'$VBOX_VERSION'-'$VBOX_PACKAGE_NO$VBOX_SEPARATOR'Debian'$VBOX_SEPARATOR$1'_'$arch'.deb'
	local vboxExtensionPack='Oracle_VM_VirtualBox_Extension_Pack-'$VBOX_VERSION'-'$VBOX_EXTENSION_NO'.vbox-extpack'
	local vboxExtPackURL=$VBOX_DOWNLOAD_SERVER$VBOX_VERSION'/'$vboxExtensionPack
	local vboxNonOseURL=$VBOX_DOWNLOAD_SERVER$VBOX_VERSION'/'$debName
	log_function_data "debName: $debName\nvboxNonOseURL: $vboxNonOseURL"

	if [ ! -d $VBOX_INSTALL_PATH ];then
		mkdir $VBOX_INSTALL_PATH
	fi
	cd $VBOX_INSTALL_PATH

	if [ ! -f $debName ];then
		echo "${S}Downloading package ${C}$debName${S}...${N}"
		wget -O $debName $vboxNonOseURL
		if [ "$?" -gt 0 ];then
			echo "${M}Removing failed package remnants from bad download...${N}"
			rm -f $debName
			error_handler 190 "$debName"
			downloadError=1
		fi
	else
		echo "${S}Using previously downloaded package: ${C}$debName${N}"
	fi
	if [ -n "$( grep -Es '^[4-9]' <<< $VBOX_VERSION )" ];then
		if [ ! -f $vboxExtensionPack ];then
			echo "${S}Downloading package ${C}$vboxExtensionPack${S}...${N}"
			wget -O $vboxExtensionPack $vboxExtPackURL
			if [ "$?" -gt 0 ];then
				#error_handler 190 "$vboxExtensionPack"
				downloadError=0 # going to not worry about this for now
				echo "${W}Error: $vboxExtensionPack failed to download, continuing anyway.${N}"
				echo "${M}Removing failed package remnants from bad download...${N}"
				rm -f $vboxExtensionPack
			fi
		else
			echo "${S}Using previously downloaded package: ${C}$vboxExtensionPack${N}"
		fi
	fi

	if [ -s "$debName" -a "$downloadError" -eq 0 ];then
		echo "${S}Installing non free debian virtual box deb now...${N}"
		 # 3.1 depends on this package
		if [ -z "$( check_package_status 'libqt4-opengl' 'i' )" -a -n "$( check_package_status 'libqt4-opengl' 'c' )" ];then
			package_installer 'libqt4-opengl'
		fi
		# dpkg -i $debName 2>> $LOG_FILE || error_handler 191 $debName
		dpkg -i $debName 2>> $LOG_FILE 2>&1 || installError=1
		if [ "$APT_TYPE" == 'apt-get' ];then
			echo "${S}Running ${C}$APT_TYPE install -f${S} to update any missing packages...${N}"
			$APT_TYPE install -f  2>> $LOG_FILE 2>&1 && installError=0 || installError=2
		elif [ "$APT_TYPE" == 'aptitude' ];then
			echo "${S}Running ${C}$APT_TYPE install $vboxName${S} to update any missing packages...${N}"
			$APT_TYPE install $WITHOUT_RECOMMENDS $vboxName  2>> $LOG_FILE 2>&1 && installError=0 || installError=2
		fi
		# note that this only runs if the above worked, otherwise shows error
		case $installError in
			0)
				if [ -f $vboxExtensionPack ];then
					if [ -n "$( type -p VBoxManage )" ];then
						vboxVersion=$( VBoxManage list extpacks | awk '/Version:/ {print $2}' )
						if [ -n "$vboxVersion" ];then
							echo "${S}Removing previously installed Vbox Extension package now...${N}"
							VBoxManage extpack uninstall "Oracle VM VirtualBox Extension Pack"
							VBoxManage extpack cleanup
						fi
					fi
					echo "${S}Installing the Vbox Extension package now...${N}"
					vboxmanage extpack install $vboxExtensionPack
					if [ "$?" -gt 0 ];then
						echo "${W}Error: $vboxExtensionPack failed to install, continuing anyway.${N}"
					fi
				fi
				echo "${S}Please note: ${C}virtualbox non-ose${S} version is started with the command: ${C}VirtualBox${S}"
				echo "(Note uppercase ${C}V${S} and ${C}B${S})"
				echo "${C}virtualbox${S} (lowercase ${C}v${S} and ${C}b${S}) is the ${C}virtualbox-ose${S} start command.${N}"
				;;
			2)
				echo "${E}Sorry, the install failed for some reason, let's find out why.${N}"
				returnValue=2
				;;
		esac
	else
		echo "${E}Sorry, the download failed for some reason, let's find out why.${N}"
		if [ -f $debName ];then
			rm -f $debName
		fi
		returnValue=1
	fi
	log_function_data "downloadError: $downloadError :: returnValue: $returnValue :: installError: $installError"

	eval $LOGPE
	print_hec
	return $returnValue
}
#install_vbox_non_ose;exit

# note: this will need to check kernel version vbox module / current vbox version
# $1 is ose or non-ose
install_vbox_module()
{
	eval $LOGPS
	local vbdv='vboxdrv'
	local isEMod=$( cat $EMOD | grep -i $vbdv )
	local vbModLoaded=$( lsmod | grep $vbdv )
	local kernelPath=$SM_KERNEL_DOWNLOADS
	# need to grab all of them, not just the main stuff
	local success='false'
	
	get_vbox_installed_version
	case $1 in
		ose)
			preinstall_cleanup # get rid of previous modules
			# then reset version information
			get_vbox_installed_version
			local vbs="virtualbox$APT_VBOX_VERSION_NU-ose-source"
			local vbo="virtualbox$APT_VBOX_VERSION_NU-ose"
			local modDebName="virtualbox$APT_VBOX_VERSION_NU-ose-"
			local vboxSource=$( dpkg -l | grep -i $vbs )
			local vboxOse=$( dpkg -l | grep -i $vbo )
			local normalizedCurrentKernel=$KERNEL_FULL
			local modDebPath=$kernelPath$normalizedCurrentKernel'/'$modDebName'*.deb'
			local modDeb=$( ls $modDebPath 2> /dev/null )
			local vboxDownloadedMod=''
			local vboxInit='/etc/init.d/vboxdrv-ose'

			# we need to check that the kernel module version matches the installed version:
			# that means it must have the right vbox version number in the deb string
			if [ -n "$VBOX_INSTALLED_VERSION" ];then
				vboxDownloadedMod=$( echo $modDeb | grep $VBOX_INSTALLED_VERSION )
				echo $LINE
			# note: here we have to make sure that the installed stuff is the same version
			# as the slh prebuilt modules. If not, we'll simply make the modules manually
	
			# since we have to be able to update modules actively, I'm removing the test for
			# loaded, that triggers a condition that requires running module install two times
			# if the old module isn't working right, or is for wrong vbox version
			# 	if [ -z "$vbModLoaded" ]
			# 	then
				if [ -n "$modDeb" -a -n "$vboxDownloadedMod" ];then
					echo "${S}Installing prebuilt vbox kernel module from kernel download directory: ${C}$kernelPath$normalizedCurrentKernel${N}"
					log_function_data "Installing prebuilt vbox kernel modules: $modDeb"
					dpkg -i $modDeb 2>> $LOG_FILE 2>&1 || error_handler 191 $modDeb
					if [ "$?" -eq 0 ];then
						success='true'
					fi
				# note that this does not exist as an option but here it is in case it ever does.
				elif [ -e $vboxInit -a -n "$vboxOse" ];then
					echo "${S}Running ${C}$vboxInit setup${S} on ${C}$vboxOse${S}...${N}"
					$vboxInit setup
					if [ "$?" -eq 0 ];then
						success='true'
					fi
				else
					# we'll only get the source if we need to build the module
					# I'm going to try to force the update as well, since otherwise users
					# will have an unmatched vbox versioning
					# 	if [ -z "$vboxSource" -o -z "$vboxDownloadedMod" ]
					# 	then
					
					echo "${S}Updating ${C}$vbo $vbs${S} now to make sure versions match...${N}"
					install_package "$vbo $vbs"
					# 	fi
					echo "${S}Building ${C}$vbdv${S} module now and running modprobe...${N}"
					log_function_data "Building $vbdv module now and running modprobe..."
					m-a a-i $vbs || error_handler 197 $vbdv
					if [ "$?" -eq 0 ];then
						success='true'
					fi
				fi
			# 		echo "${S}Ignore this error message if you see it, it's meaningless: ${C}FATAL: Module vboxdrv not found.${N}"
				if [ "$success" == 'true' ];then
					modprobe $vbdv
				fi
			else
				error_handler 186 "$vbo"
			fi
	# 		else
	# 			echo "${M}Kernel Module ${C}$vbdv${M} is already installed...${N}"
	# 			log_function_data "Kernel Module $vbdv is already installed..."
	# 		fi
			
			;;
		non-ose)
			# /usr/share/virtualbox/src/vboxhost/vboxdrv/build_in_tmp install KERN_DIR=/usr/src/linux-headers-`uname -r`
			local nonOse="virtualbox$APT_VBOX_VERSION_NU"
			# make sure vbox non ose is installed
			local nonOseInstalled=$( dpkg -l | awk '{print $2}' | grep -E "^$nonOse$" )
			local vboxInit='/etc/init.d/vboxdrv'
	
			if [ -n "$nonOseInstalled" -a -e "$vboxInit"  ];then
				echo $LINE
				echo "${S}Running ${C}$vboxInit setup${S} on ${C}$nonOse${S}...${N}"
				$vboxInit setup
				# dpkg-reconfigure $nonOse
				if [ "$?" -eq 0 ];then
					success='true'
				fi
			else
				error_handler 186 "$nonOse"
			fi
			;;
	esac

	if [ "$success" == 'true' ];then
		# we're going to run this stuff for ose and non-ose now to make sure all users
		# get this, that might help some fringe cases
		if [ -z "$isEMod" ];then
			echo $vbdv >> $EMOD
		fi
		modprobe $vbdv
		echo "${C}$vbdv${S} module should now be up and running.${N}"
	else
		echo "${E}There was an error building the vbox module.${N}"
	fi
	eval $LOGPE
	print_hec
}
#install_vbox_module

preinstall_cleanup()
{
	eval $LOGUS
	local previousVbox='' oldVbSource="virtualbox-source"
	local previousVbm='' vbdv='vboxdrv'
	local vbModLoaded=$( lsmod | grep $vbdv )

	echo $LINE
	echo "${S}Doing some basic pre module install preparations and cleanup...${N}"
	if [ -n "$vbModLoaded" ];then
		rmmod vboxdrv 1>> $LOG_FILE 2>> $LOG_FILE
	fi

	previousVbm=$( COLUMNS=200 dpkg -l | cut -d ' ' -f 3 | grep -E '(virtualbox-modules|virtualbox-[2-9]..-modules)' )
	if [ -n "$previousVbm" ];then
		dpkg --purge $previousVbm  1>> $LOG_FILE 2>> $LOG_FILE
	fi

	oldVbSource=$( COLUMNS=200 dpkg -l | cut -d ' ' -f 3 | grep $oldVbSource )
	if [ -n "$oldVbSource" ];then
		dpkg --purge $oldVbSource 1>> $LOG_FILE 2>> $LOG_FILE
	fi

	previousVbox=$( COLUMNS=200 dpkg -l | cut -d ' ' -f 3 | grep -E '(virtualbox-ose-modules|virtualbox-[2-9]..-modules)' )
	if [ -n "$previousVbox" ];then
		dpkg --purge $previousVbox  1>> $LOG_FILE 2>> $LOG_FILE
	fi
	eval $LOGUE
}
# getent passwd 1000|cut -d\: -f1
# your first user is ${1st_user}. Press ENTER to use that, or type the username'
add_vbox_user()
{
	eval $LOGPS
	local userExists=''

	echo $LINE
	echo "${S}In order for vbox to run, you need to add your normal user name to the ${C}vboxusers${S} group."
	echo
	if [ -z "$USER_NAME" ];then
		echo "This script can do that for you now. If you would like to have that done, please"
		echo "enter your normal login user name now, then hit enter."
		echo "(If you have already created this user/group, or want to skip this step, just hit enter)${N}"

		read USER_NAME
	else
		echo "${S}Using the user name you provided: ${C}$USER_NAME${N}"
	fi

	# check to see user actually exists, use passwd because someone reported a looping
	# error here using the test on /home. Tightened test to include : to close name
	# old test: [ -n "$( ls /home | grep $USER_NAME )" ]
	userExists=$( grep -Eo "^$USER_NAME:" /etc/passwd )

	if [ "$USER_NAME" != '' ];then
		log_function_data "Using USER_NAME: $USER_NAME"
		if [ -n "$userExists" ];then
			echo "${M}NOTE: the new group will not be available to ${C}$USER_NAME${M} until they logout and log back in.${N}"
			adduser $USER_NAME vboxusers
		else
			echo "${E}The user name ${C}$USER_NAME${E} does not appear to exist, please try again...${N}"
			log_function_data "Error: USER_NAME: $USER_NAME does not exist in /etc/passwd"
			USER_NAME='' # must be reset here to null or loops endlessly
			add_vbox_user
		fi
	fi
	eval $LOGPE
}

install_vbox_addons()
{
	eval $LOGPS
	
	local vboxLib='/usr/lib/virtualbox/' vboxAddDir='additions'
	local vboxAddonFile='VBoxGuestAdditions_'$VBOX_INSTALLED_VERSION'.iso'
	local vboxAddonName='VBoxGuestAdditions.iso'
	local vboxAddonURL=$VBOX_DOWNLOAD_SERVER$VBOX_INSTALLED_VERSION'/'$vboxAddonFile
	local downloadError=0 returnValue=0
	
	log_function_data "vboxAddonURL: $vboxAddonURL"

	echo $LINE
	
	if [ ! -d $vboxLib ];then
		echo "${E}Virtualbox does not appear to be installed! Please install it first!${N}"
		returnValue=2
	elif [ -z "$VBOX_INSTALLED_VERSION" ];then
		error_handler 188 "VBOX_INSTALLED_VERSION"
		returnValue=3
	else
		cd $vboxLib
		# for some reason debian/vbox devs changed the default download
		# path for the addons, and it doesn't match, so here the old
		# original one, if present, gets removed, and the new one gets a new
		# directory created, and it's put in that one.
		if [ -f $vboxAddonName ];then
			rm -f $vboxAddonName
		fi
		if [ ! -d $vboxAddDir ];then
			mkdir $vboxAddDir
		fi
		cd $vboxAddDir
		wget -O $vboxAddonFile $vboxAddonURL
		if [ "$?" -gt 0 ];then
			error_handler 190 "$vboxAddonFile"
			downloadError=1
		fi

		if [ -s $vboxAddonFile -a "$downloadError" -eq 0 ];then
			mv $vboxAddonFile $vboxAddonName
			echo "${S}Please note: to use the ${C}$VBOX_INSTALLED_VERSION${S} iso, simply run vbox, then start your virtual machine."
			echo "When it is running, you will see a ${C}Devices${S} menu item. Select ${C}Install Guest Additions${S}"
			echo "vbox will discover the iso you just downloaded and use it for drivers and other tools.${N}"
		else
			echo "${E}Sorry, the download failed for some reason, let's find out why.${N}"
			returnValue=1
		fi
	fi
	echo
	log_function_data "returnValue: $returnValue :: downloadError: $downloadError"
	print_hec
	eval $LOGPE
	return $returnValue
}
# install_vbox_addons
########################################################################
#### OPTIONS
########################################################################
# keep this above getopts to keep it readable
# args: $1 if err or not, $2 extra data

show_options()
{
	if [ "$1" == 'err' ];then
		echo "${W}Sorry, one of your arguments is not a supported option.${N}"
		echo "Please check the following options and try again."
		echo $LINE
	fi
	echo "These are your supported options:"
	echo "-A Run the any any install non-interactively."
# 	echo "-g Lets you use a specific gcc version to compile module. Example: -g 4.1"
	echo "-h View this help menu."
	echo "-j Alternate text/output script colors. Requires this syntax: -j 0 (sets to monochrome )"
	echo "   -j 1 (default); -j 2 (pale); -j 3 (earthy); -j 4 (dark - for light console background)"
	echo "-M Run the vbox module install non-interactively."
	echo "-R Skips self updating feature. No restart."
	echo "-u Enter the username that will be used for vbox group membership and other functions."
	echo "   Best used with non-interactive mode, but is fine for normal mode too. Example: svmi -u jeff"
	echo "-U Forces $SCRIPT_NAME to update itself, must be root, but can be in x. Exits after."
	echo "-v Prints $SCRIPT_NAME current version information. Exits after."
	echo "-V Allows you try a specific Version of vbox/vmware player."
	echo "   Supported vbox non ose versions: $VBOX_VERSIONS"
	echo "   Supported alternate vmware player: $VMPLAYER_NUMBER_PREVIOUS"
	echo "   Example: svmi -V 1.5.2 [or] svmi -V 2.0.5"
	echo "-Y Clean script download and backup files. Shows a list of cleanup actions to carry out, including script uninstaller."
	echo "   Can be run in X, as root."
	echo "-Z Skips connection test. Use this if $SCRIPT_NAME gives you connection failed error but"
	echo "   you are sure your connection is fine."
	if [ "$1" == 'full' ];then
		echo ''
		echo "Developer and Testing Options (Advanced):"
		echo "-! 1 - Sets flag B_TESTING_1='true' to trigger testing condition 1."
		echo "-! 2 - Sets flag B_TESTING_2='true' to trigger testing condition 2."
		echo "-! 3 - Sets flag B_SKIP_FUNCTION='true' to turn off some functions."
		echo "-! 4 - Sets flags B_TESTING_1='true' and B_TESTING_2='true'."
		echo "-! 5 - Sets flags B_TESTING_1='true' and B_SKIP_FUNCTION='true'."
		echo "-! 10 - Triggers an update from the primary dev download server."
		echo "-! 11 - Triggers an update from svn branch one - if present, of course."
		echo "-! 12 - Triggers an update from svn branch two - if present, of course."
		echo "-! <http://......> - Triggers an update from whatever server you list."
	fi
	echo

	if [ "$1" == 'err' ];then
		exit 1
	else
		exit 0
	fi
}

# args: $1 - "$@"
get_options()
{
	case $1 in
		--help|-h)
			if tty > /dev/null ;then
				show_options
			else
				echo "You cannot use the $SCRIPT_NAME help option in an IRC client!"
				exit 1
			fi
			;;
		--version|-v)
			# if showing in irc, kill the colors
			if ! tty > /dev/null ;then
				SCRIPT_COLORS=0
				set_script_colors
			fi
			print_information
			exit 0
			;;
	esac
	
	while getopts ABHj:MpP:RSuUV:YZ!: opt
	do
		case $opt in
			A) AUTORUN_ANYANY='true'
				START_OPTIONS=$START_OPTIONS' -A'
				;;
			B) AUTORUN_VBOX='true'
				START_OPTIONS=$START_OPTIONS' -B'
				;;
			
			j)	if [ -n "$( grep -E '^[0-4]$' <<< $OPTARG )" ];then
					SCRIPT_COLORS=$OPTARG
					# no reason to reset the colors if they are default
					if [ "$SCRIPT_COLORS" != 1 ];then
						START_OPTIONS=$START_OPTIONS" -j $SCRIPT_COLORS"
						set_script_colors
					fi
				else
					error_handler 249 $OPTARG
				fi
				;;
			M) AUTORUN_VBOX_MODULE='true'
				START_OPTIONS=$START_OPTIONS' -M'
				;;
			p) AUTORUN_VMPLAYER='true'
				START_OPTIONS=$START_OPTIONS' -p'
				;;
			P)	if [ -n $( grep -E '^(apt-get|aptitude)$' <<< $OPTARG ) ];then
					PACKAGE_MANAGER=$OPTARG
					APT_TYPE=$OPTARG
					START_OPTIONS=$START_OPTIONS" -P $PACKAGE_MANAGER"
				else
					error_handler 249 $OPTARG
				fi
				;;
			R) SKIP_RESTART='true'
				;;
			S) AUTORUN_VMSERVER='true'
				START_OPTIONS=$START_OPTIONS' -S'
				;;
			u) USER_NAME="$OPTARG"
				START_OPTIONS=$START_OPTIONS" -u $USER_NAME"
				;;
			U) FORCE_UPDATE='true'
				;;
			V) if [ -z "$( grep "$OPTARG:" <<< $VBOX_PREVIOUS )" -a -z "$( grep "^$OPTARG$" <<< $VMPLAYER_NUMBER_PREVIOUS )" ];then
					echo "${E}The -V option supports either non-ose vbox versions: ${C}$VBOX_VERSIONS"
					echo "${E}or vmware player previous version: ${C}$VMPLAYER_NUMBER_PREVIOUS${N}"
					exit 1
				else
					if [ -n "$( grep "$OPTARG:" <<< $VBOX_PREVIOUS )" ];then
						VBOX_VERSION="$OPTARG" # assign to main version global
						VBOX_PACKAGE_NO=$( echo $VBOX_PREVIOUS | grep -oE "$VBOX_VERSION:[0-9]{5,7}:[~_]" | cut -d ':' -f 2 )
						VBOX_SEPARATOR=$( echo $VBOX_PREVIOUS | grep -oE "$VBOX_VERSION:[0-9]{5,7}:[~_]" | cut -d ':' -f 3 )
						VBOX_EXTENSION_NO=$( echo $VBOX_PREVIOUS | grep -oE "$VBOX_VERSION:[0-9]{5,7}:[~_]:[0-9]{5,7}" | cut -d ':' -f 4 )
						#echo vb pn $VBOX_PACKAGE_NO
					elif [ -n "$( grep "^$OPTARG$" <<< $VMPLAYER_NUMBER_PREVIOUS )" ];then
						VMPLAYER_NUMBER=$VMPLAYER_NUMBER_PREVIOUS
						VMPLAYER_BUILD=$VMPLAYER_BUILD_PREVIOUS
						VMPLAYER_VERSION=$VMPLAYER_VERSION_PREVIOUS
						VMWARE_Z=$VMWARE_Z_PREVIOUS
					fi
					V_ALT_VERSION="$OPTARG" # and set the alt as well
					START_OPTIONS=$START_OPTIONS" -V $V_ALT_VERSION"
				fi
				;;
			Y)	clean_script_data
				;;
			Z) SKIP_CONNECT='true'
				START_OPTIONS=$START_OPTIONS' -Z'
				;;
			H)	show_options 'full'
				;;
			## debuggers and testing options
			!)	# test for various supported methods
				case $OPTARG in
					1)	B_TESTING_1='true'
						;;
					2)	B_TESTING_2='true'
						;;
					3)	B_SKIP_FUNCTION='true'
						;;
					4)	B_TESTING_1='true'
						B_TESTING_2='true'
						;;
					5)	B_TESTING_1='true'
						B_SKIP_FUNCTION='true'
						;;
					10)
						check_update_script "$SCRIPT_NAME" "$SCRIPT_DOWNLOAD_DEV" 'dev server'
						;;
					11)
						check_update_script "$SCRIPT_NAME" "$SCRIPT_DOWNLOAD_BRANCH_1" 'svn: branch one server'
						;;
					12)
						check_update_script "$SCRIPT_NAME" "$SCRIPT_DOWNLOAD_BRANCH_2" 'svn: branch two server'
						;;
					120)
						SM_INSTALL='true'
						S=${CALLER_DEF} # change standard text color to caller standard text
						BAR=${S}$BA${N}
						LINE=${S}$LI${N}
						START_OPTIONS=$START_OPTIONS' -D'
						;;
					http*)
						check_update_script "$SCRIPT_NAME" "$OPTARG" 'alt server'
						;;
# 					20)
# 						PATCH_DOWNLOAD="$SCRIPT_DOWNLOAD_BRANCH_1"
# 						;;
# 					21)
# 						PATCH_DOWNLOAD="$SCRIPT_DOWNLOAD_BRANCH_2"
# 						;;
					*)	error_handler 247 "$OPTARG"
						;;
				esac
				START_OPTIONS="$START_OPTIONS -! $OPTARG"
				;;
			*) show_options err
				;;
		esac
	done
}

########################################################################
####  EXECUTE
########################################################################
# this must be set before anything else runs in script, -j will reset to no colors
set_script_colors
get_options "$@"
# run all script checks etc

### if this exits with error, no lib files will be downloaded
if [ "$B_SKIP_FUNCTION" != 'true' ];then
	basic_startup_tests
fi
cleanup_update_files
### update everything, restart if not run from smxi
if [ "$SKIP_RESTART" != 'true' -a "$SM_INSTALL" != 'true' -a "$B_SKIP_FUNCTION" != 'true' ];then
	check_update_script $SCRIPT_NAME "$SCRIPT_DOWNLOAD" 'default server'
fi
set_test_data # this will set other test data for debugging
set_testing_version # to test alternate patches/versions for boolean tests

create_log
# will run non interactive and set the AUTO_UPDATE flag
run_non_interactive
if [ -z "$PACKAGE_MANAGER" -a "$SM_INSTALL" != 'true' -a "$AUTO_UPDATE" != 'true' ];then
	check_apt_aptitude
fi

print_information
check_install_tools

if [ "$AUTO_UPDATE" != 'true' ];then
	vm_main_selector
fi

exit 0
###**EOF**###